代理模式是通过创建代理类(Proxy)的方式来访问服务,代理类通常会有一个委托类对象,代理类不会自己实现真正服务,而是通过委托类对象的相关方法来提供服务。可以用来实现被代理类的功能增强,而不入侵被代理类的源代码。
对目标对象的每个方法的增强都是手动完成的,每个目标对象对应一个代理类,这样会产生过多的代理类;并且当接口需要增加、删除、修改方法的时候,目标对象与代理类都要同时修改,不易维护。
执行结果:
代理类在程序运行时创建的代理方式被成为动态代理。动态代理相较于静态代理的优势在于可以很方便的对代理类的所有函数进行统一管理,不需要针对每个目标类都单独创建一个代理类。
从 JVM 角度来说,动态代理是在运行时动态生成类字节码,并加载到 JVM 中的。
在 Java 动态代理机制中 InvocationHandler 接口和 Proxy 类是核心。
Proxy 类中使用频率最高的方法是:newProxyInstance() ,这个方法主要用来生成一个代理对象。
当我们的动态代理对象调用一个方法时,这个方法的调用就会被转发到实现InvocationHandler 接口类的 invoke 方法来调用。
总结:通过Proxy 类的 newProxyInstance() 创建的代理对象在调用方法的时候,实际会调用到实现InvocationHandler 接口的类的 invoke()方法。 你可以在 invoke() 方法中自定义处理逻辑,比如在方法执行前后做什么事情。
Proxy.newProxyInstance(ClassLoader loader,Class\<?\>[] interfaces,InvocationHandler h)
方法创建代理对象;执行结果:
在 CGLIB 动态代理机制中 MethodInterceptor 接口和 Enhancer 类是核心。
JDK 动态代理只能代理实现了接口的类或者直接代理接口,而 CGLIB 可以代理未实现任何接口的类。
需要自定义 MethodInterceptor 并重写 intercept 方法,intercept 用于拦截增强被代理类的方法。
执行结果
Spring 中的 AOP 模块中:如果目标对象实现了接口,则默认采用 JDK 动态代理,否则采用 CGLIB 动态代理。
Update your browser to view this website correctly. Update my browser now