静态代理
这里我们介绍了静态代理,也知道了静态代理的一些缺点
代理模式-静态代理
下面我们就介绍动态代理(基于继承,cglib动态代理)
动态代理
1:CGLib的基本介绍
看一下CGLib的基本结构,下图所示,代理类去继承目标类,每次调用代理类的方法都会被方法拦截器拦截,在拦截器中才是调用目标类的该方法的逻辑,结构还是一目了然的;
使用一下CGLib,在JDK动态代理中提供一个Proxy类来创建代理类,而在CGLib动态代理中也提供了一个类似的类Enhancer;
使用的CGLib版本是3.3.0,我用的maven项目进行测试的,首先要导入cglib的依赖
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
2:目标类
目标类(一个公开方法,打lol,另外一个用final修饰,学习):
package com.lingaolu.bean; /** * @author 林高禄 * @create 2020-11-09-10:30 */ public class Me { public String lol() { System.out.println("登录账号:林高禄"); /* * 排位,组队 * 补刀,抓人,打团。提高意识......等一系列操作 */ return "铂金2"; } final public void study(){ System.out.println("写博客"); } }
3:方法拦截器
package com.lingaolu.service; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * @author 林高禄 * @create 2020-11-09-23:13 */ public class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("这里是对目标类进行增强!!!"); //注意这里的方法调用,不是用反射哦!!! Object object = proxy.invokeSuper(obj, args); return object; } }
4:测试类
package com.lingaolu; import com.lingaolu.bean.Me; import com.lingaolu.service.MyMethodInterceptor; import net.sf.cglib.core.DebuggingClassWriter; import net.sf.cglib.proxy.Enhancer; import org.junit.Test; /** * @author 林高禄 * @create 2020-11-03-9:22 */ public class TestDemo { @Test public void testProxy(){ // 在指定目录下生成动态代理类,我们可以反编译看一下里面到底是一些什么东西 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\java\\java_workapace"); // 创建Enhancer对象,类似于JDK动态代理的Proxy类,下一步就是设置几个参数 Enhancer enhancer = new Enhancer(); // 设置目标类的字节码文件 enhancer.setSuperclass(Me.class); // 设置回调函数 enhancer.setCallback(new MyMethodInterceptor()); // 这里的creat方法就是正式创建代理类 Me proxyMe = (Me)enhancer.create(); // 调用代理类的lol方法 proxyMe.lol(); // 分隔符 System.out.println("------------------------------"); // 调用代理类的study方法 proxyMe.study(); } }
这里只介绍如何使用,至于原理,可以参考这篇