之前学了JDK动态代理,每次被代理的类必须有实现接口这样就不太友好了吧,所以CGlib就出现了
- 针对类来实现代理(本来就该这样)
- 对指定木木飙泪产生一个子类,通过方法拦截技术拦截所有的父类方法调用
现在我们建立一个Train类,作为目标类:
package com.ee.chapter1.cglibproxy;
public class Train {
public void move(){
System.out.println("火车行驶中。。。");
}
}
而我们的代理类要做的事情其实就是继承这个父类来调用父类的方法。建立代理类实现拦截器方法,这后天开发经常会使用,spring开发现在大多使用aop拦截了Interceptor拦截器使用那是较少了。
package com.ee.chapter1.cglibproxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
private Enhancer enhancer=new Enhancer();
public Object getProxy(Class clazz){
//设置代理类的父类,其实代理类就是要继承我们传入的Train
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("日志开始打印");
methodProxy.invokeSuper(o,objects);
System.out.println("日志结束打印");
return null;
}
}
其实上面的方法的调用跟jdk的动态代理是很相似的。
注意:java工程需要引入cglib的架包才能使用,,如果直接使用spring工程则不需引入cglib架包,spring带有该架包。
编写测试类:
package com.ee.chapter1.cglibproxy;
import org.junit.jupiter.api.Test;
public class TestCGlib {
@Test
public void cglib(){
CglibProxy cglibProxy=new CglibProxy();
Train train=(Train) cglibProxy.getProxy(Train.class);
train.move();
}
}
运行结果如下:
这里
public class CglibProxy implements MethodInterceptor其实就是拦截了对父类方法的调用,其实这里可以引申到后台在前端请求到Controller层的时候,就被拦截到输出日志,或者权限认证等操作,正常controller层应该是不做业务逻辑处理的,所以在进入之前先到日志拦截等做处理等,再进入控制器,执行完控制器后又可以拦截,这里可以形成一个spring的项目架构的思路。