上一章写到通过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包依赖

创建数据访问类

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代理是对类做代理,它的原理是从内存中创建一个对象, 其对象是你目标对象(类)的子类。它的运行是对原目标对象的方法对象生成了一个代理的方法对象,通过执行代理方法对象的执行父类的原方法来最终运行其子类(代理对象)的方法。