上篇介绍了静态代理模式
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
欢迎留言交流