上一章写到通过jdk的代理来增强一个类中的方法,今天我教大家使用另外一种方式来实现动态代理
什么是CGLIB代理?
CGLIB是一个强大、高性能的字节码生成库,它用于在运行时扩展Java类和实现接口;本质上它是通过动态的生成一个子类去覆盖所要代理的类(非final修饰的类和方法)。Enhancer可能是CGLIB中最常用的一个类,和jdk中的Proxy不同的是,Enhancer既能够代理普通的class,也能够代理接口。Enhancer创建一个被代理对象的子类并且拦截所有的方法调用(包括从Object中继承的toString和hashCode方法)。Enhancer不能够拦截final方法,例如Object.getClass()方法,这是由于Java final方法语义决定的。基于同样的道理,Enhancer也不能对final类进行代理操作。
CGLIB代理示意图
引入jar包依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.12</version>
</dependency>
|
创建数据访问类
package com.user.cglib.dao;
/**
* @descrption 用户数据访问接口实现类
* @auth lizhilun
*/
public class UserDao {
/**
* 新增
*/
public void add() {
System.out.println("用户add方法执行。。。。。");
}
}
|
创建生成代理对象的类
package com.user.cglib.dao;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @descrption 用户数据访问接代理类
* @auth lizhilun
*/
public class CglibUserDao implements MethodInterceptor {
/**
* 生成代理对象
* @return
*/
public UserDao createUserDao(){
//增强类:用于在内存中创建类
Enhancer enhancer = new Enhancer();
//设置父类为UserDao
enhancer.setSuperclass(UserDao.class);
//设置回调
enhancer.setCallback(this);
//生成代理对象
UserDao userDao = (UserDao) enhancer.create();
return userDao;
}
/**
* 代理方法进行增强
* @param o 代理对象
* @param method 目标对象方法
* @param objects 方法的参数
* @param methodProxy 对原目标对象的方法生成的代理
* @return
* @throws Throwable
*/
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("权限校验。。。。。");
//第一个参数为代理对象 第二个参数为原方法的所有参数 invokeSuper:执行父类
Object obj = methodProxy.invokeSuper(o, objects);
System.out.println("日志记录。。。。。");
return obj;
}
}
|
测试
package com.user.test;
import com.user.cglib.dao.CglibUserDao;
import com.user.cglib.dao.UserDao;
/**
* @descrption 测试Cglib代理
* @auth lizhilun
*/
public class CglibTest {
public static void main(String[] args) {
UserDao userDao = new CglibUserDao().createUserDao();
userDao.add();
}
}
|
CGLIB的原理概述
CGLIB代理是对类做代理,它的原理是从内存中创建一个对象, 其对象是你目标对象(类)的子类。它的运行是对原目标对象的方法对象生成了一个代理的方法对象,通过执行代理方法对象的执行父类的原方法来最终运行其子类(代理对象)的方法。
本文暂时没有评论,来添加一个吧(●'◡'●)