首先明确两个概念:业务代码和关注点代码
业务代码就是目标对象中执行的特有方法。
关注点代码是多个不同类别的目标对象中所存在的相同代码。
AOP编程的目的是分离目标对象的业务代码与关注点代码,使得关注点代码只写一次,而在执行业务代码的时候会动态植入关注点代码。
目标对象 IUserDao与UserDao
public interface IUserDao {
void save();
void find();
}
// 目标对象
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("模拟: 保存用户!");
}
@Override
public void find() {
System.out.println("查询");
}
}
关注点代码类
@Component
public class MyAOP {
//写关注点代码 关注点代码只写一次,之后通过代理对象动态植入到目标对象的业务代码中
public void beginTransaction(){
System.out.println("开启事务..");
}
public void commit(){
System.out.println("提交事务..");
}
}
代理工厂
public class ProxyObjectFactory {
/**
* 生成动态代理对象
* @param target 目标对象
* @param MyAop 提供关注点代码的对象
* @return
*/
public Object getProxyInstance(final Object target, final MyAOP MyAop){
Object proxyInstance = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
Object result = null;
if("save".equals(methodName)){
MyAop.beginTransaction();
result = method.invoke(target, args);
MyAop.commit();
}else{
result = method.invoke(target, args);
}
return result;
}
}
);
return proxyInstance;
}
}
applicationContext中配置
<!--myaop工厂方法生成代理对象-->
<bean id="proxyFactory" class="hfi.bellychang.myaop.ProxyObjectFactory"/>
<bean id="proxyInstance" factory-bean="proxyFactory" factory-method="getProxyInstance">
<constructor-arg index="0" ref="userDao"/>
<constructor-arg index="1" ref="myAOP"/>
</bean>
注意其中注入对象的方式,使用了工厂方法注入方式。
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/applicationContext.xml")
public class AppTest {
@Resource
IUserDao proxyInstance;
@Test
public void testMyaop() {
//未加代理之前 只执行目标对象的业务代码
IUserDao userDao = new UserDao();
userDao.save();
userDao.find();
//使用代理对象 将只写一次的关注点代码动态植入到目标对象的业务代码中
//
proxyInstance.save();
proxyInstance.find();
}
}
可以在applicationContext中为多个不同类别的目标对象配置相应的代理对象,就可以实现将MyAOP中的关注点代码注入到多个目标对象的业务代码中。