专业的编程技术博客社区

网站首页 > 博客文章 正文

CGLIB来实现动态代理(动态代理与cglib实现的区别)

baijin 2024-09-04 02:03:22 博客文章 12 ℃ 0 评论

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

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表