Spring中bean的生命周期图
Spring AOP的原理
- 静态代理模式
//目标接口
public interface PersonDao{
public void savePerson();
}
//目标类
public class PersonDaoImpl implements PersonDao{
@Override
public void savePerson(){
System.out.println("save person");
}
}
//代理类
public class PersonDaoProxy implements PersonDao{
private PersonDao personDao;
private Transaction transaction;
public PersonDaoProxy(PersonDao personDao,Transaction transaction) {
super();
this.personDao = personDao;
this.transaction = transaction;
}
public void savePerson(){
this.transaction.beginTransaction();//开启事务
this.personDao.savePerson();//调用的是目标方法
this.transaction.commit();//事务提交
}
}
缺点:有多少目标类就要写多少个代理类,在代理类中,每一个方法都要写事务的开启和事务的提交
2. JDK动态代理模式
public void personDaoProxy(){
final Transaction transaction = new Transaction();
final Object target = new PersonDaoImpl();
/**
* 第一个参数
* 目标类的类加载器
* 第二个参数
* 目标类实现的所有的接口
* 第三个参数
* 拦截器
*/
PersonDao proxy = (PersonDao)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();
if(methodName.equals("savePerson")
||methodName.equals("update")){
transaction.beginTransaction();//开启事务
method.invoke(target, args);//调用目标方法
transaction.commit();//事务提交
}else{//读的操作
method.invoke(target, args);
}
return null;
}
});
proxy.savePerson();
}
缺点:在方法判断的时候,若在生产环境下,如果方法特别多,这里的判断就相当多,而且仅仅处理了事务权限,日志未处理
3. cglib动态代理模式
利用字节码的增强功能产生代理对象,代理对象是目标类的子类,不需要接口就可以做
public void personDaoProxy(){
final Transaction transaction = new Transaction();
final Object target = new PersonDaoImpl();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy arg3) throws Throwable {
transaction.beginTransaction();
method.invoke(target, args);
transaction.commit();
return null;
}
});
PersonDaoImpl proxy = (PersonDaoImpl)enhancer.create();//产生代理对象
proxy.savePerson();
}