三、CGLIB 代理机制
学习了JDK 代理机制后再学习 CGLIB 代理,感觉二者有很多相似处,区别只是细微的书写习惯。
1、特点:
1)CGLIB 是第三方开源的,所以使用的使用的时候需要去官网下载对应的包。
2)好消息是 在spring3.2 版本中,spring-core.jar 中集成了cglib.jar。
3)CGLIB代理可以直接对实现类进行代理,不需要创建接口。
2、原理:
JDK代理是通过创建父级接口的形式进行代理,而CGLIB代理的原理是创建被代理对象的子类进行代理。
3、使用 : demo的形式展示
1)被代理对象 : StudentDao
public class StudentDao {
public void addStudent(){
System.out.println("添加一个学生....");
}
public void updateStudent(){
System.out.println("更新一个学生....");
}
}
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class StudentProxy implements MethodInterceptor{
//第1步:创建被代理对象
private StudentDao studentDao;
public StudentProxy(StudentDao studentDao){
this.studentDao = studentDao;
}
//第2步:创建代理对象
public StudentDao createStudentDao(){
Enhancer enhancer = new Enhancer();//创建代理工具对象
enhancer.setSuperclass(studentDao.getClass());//创建子类
enhancer.setCallback(this);//设置回调函数,这里的this是MethodInterceptor的实现类对象
return (StudentDao) enhancer.create();//返回代理对象,被代理对象的子类对象
}
//第1.5步:处理拦截的方法
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if(method.getName().equals("addStudent")){
System.out.println("这是日志信息..........");
Object result = methodProxy.invokeSuper(proxy, args);
return result;
}else{
return methodProxy.invokeSuper(proxy, args);
}
}
}
步骤:跟JDK代理很类似,只是一些地方的书写格式变了而已。
第1步:引入被代理对象,这里是StudentDao
第2步:创建代理对象并返回。
这里创建代理对象的方法就是那四句(包含enhancer),Enhancer类是CGLIB创建代理对象的工具类,大家只要知道这样写就可以获得代理对象即可。
其中,第三行的设置回调函数中的this是MethodInterceptor接口的实现类对象,同样需要实现MethodInterceptor接口。
第1.5步:处理拦截的方法。
这里需要注意的是返回的是 methodProxy.invokeSuper(proxy,args) 因为代理的本质是产生子类,这里返回的执行方法依然是父类原本的方法。
4、测试结果展示
public class TestCGLIBProxy {
public static void main(String[] args) {
//不进行代理
System.out.println("========================不进行代理===========================");
StudentDao studentDao = new StudentDao();
studentDao.addStudent();
studentDao.updateStudent();
//进行代理
System.out.println("========================不进行代理===========================");
StudentDao studentDao2 = new StudentDao();
StudentProxy studentProxy = new StudentProxy(studentDao2);
studentDao2 = studentProxy.createStudentDao();
studentDao2.addStudent();
studentDao2.updateStudent();
}
}
控制台打印语句:
========================不进行代理===========================
添加一个学生....
更新一个学生....
========================不进行代理===========================
这是日志信息..........
添加一个学生....
更新一个学生....
上一篇:JDK代理机制 学习总结