上篇介绍了静态代理模式
https://blog.csdn.net/liufangbaishi2014/article/details/90673154
在看本文之前,读者最好,先浏览一下
既然已经有了静态代理模式,为什么还要有动态代理模式呢?
那我们先来谈下静态代理模式的局限性:
1.一个代理类只能代理一类(实现了特定接口的)对象;
2.一个代理类只能代理一个(特定接口的)方法;
就像是我们想要卖房子,既需要找一个代理,帮我们把房子卖了,同时,还需要找另外一个代理,帮我们把家具卖了。我能不能直接找个万能的代理,直接把这两件事儿,甚至是n件事(比如还要卖车)一起办了呢?
动态代理模式可以办到。通过proxy产生某一个类(需要实现某个接口)的代理对象,帮该类做一些操作。最终,该类所有的类的方法在执行之前,都会先执行代理对象的invoke方法,并把原方法的名称和参数传入。样例代码如下:
package anjz.anjz;
import org.objectweb.asm.commons.GeneratorAdapter;
public interface Test {
void dosomesthing();
}
package anjz.anjz;
public class TestImpl implements Test{
public void dosomesthing() {
System.out.println("被代理的类做的事情");
}
}
package anjz.anjz;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TestInterface implements InvocationHandler{
private Object target=null;//保存真实业务对象
/**
* 返回动态代理类的对象,这样用户才可以利用代理类对象去操作真实对象
* @param obj 包含有真实业务实现的对象
* @return 返回代理对象
*/
public Object getProxy(Object obj) {
this.target=obj;//保存真实业务对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//自定义逻辑
System.out.println("方法前边 -自定义逻辑");
method.invoke(target, args);
//自定义逻辑
System.out.println("方法后边 -自定义逻辑");
return null;
}
public static void main(String[] args) {
TestImpl tImpl = new TestImpl();
TestInterface tInterface = new TestInterface();//新建代理对象,代理对象中有对方法的拦截和处理逻辑
Test test= (Test)tInterface.getProxy(tImpl);//产生一个和tImpl对象实现了同一个接口的代理类
test.dosomesthing();
}
}
这里面用到了类Proxy,用来通过调用newProxyInstance方法产生代理对象;
一个InvocationHandler接口,用来拦截目标类对方方法,以插入代理逻辑。
讲到这里大家有没有发现一个问题,代理在做的事情,就是AOP所做的事情,就是拦截目前方法,插入我们想要的逻辑。
你想的没错,Spring的AOP就是这么实现的。只不过Spring将AOP配置化了,可以通过xml的配置或者注解完成,但是最后的实现思路,还是上边的这套逻辑。
Spring AOP编程在我的实际应用中,除了特定的几个场景(权限控制、日志打印),用的并不是特别多。而他在某一方面的应用却十分常见,就是事物管理。
spring通过在数据库操作前后插入事物回滚逻辑,就可以进行事物管理。我们在日常编程中,一般是定义一些通用方法,只要以这些方法开头的如update 、insert开头的方法,都进行事物管理。
参考文档:
https://www.jianshu.com/p/fc285d669bc5
欢迎留言交流