使用CGLIB实现动态代理

Posted auge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用CGLIB实现动态代理相关的知识,希望对你有一定的参考价值。

参考:https://blog.csdn.net/yhl_jxy/article/details/80633194#comments

CGLIB动态代理

定义:CGLIB(code genaration libary), 代码自动生成类库。

在程序运行中自动生成扩展类和实现java接口,是一个强大的高性能的代码生成包

CGLIB动态代理的实现

1)、导入cglib所需的jar包

2)、实现MethodIntercetor类,实现代理类对象的具体逻辑

       重写intercept()方法,在intercept方法中实现代理的逻辑

      intercept(Object o, Method method, Object[] Objects, MehodProxy methodProxy )

       o: 被代理类对象

        method: 被代理类的方法

    objects: 被代理类方法的参数

     methodProxy: 调用被代理类对象的参数

3)、使用Enhance生成代理类对象

          enhance.create() //生成代理类对象

使用CGLIB实现延迟加载

MehodInterceptor实现类:

/**
 * 实现代理的逻辑
 * 步骤:
 *   --: 1、实现MethodInterceptor拦截器
 *        o: 被代理对象
 *        method: 被代理对象的方法
 *        objects: 被代理对象的方法参数
 *        methodProxy: 触发父类方法的对象
 */
public class DBQueryCglibMethodInterceptor implements MethodInterceptor 
    DBQuery dbQuery = null;
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable 
           if(dbQuery == null)
               dbQuery = new DBQuery();
           
           return dbQuery.Request();
    

真实类:

/**
 * 使用cglib来实现数据库的查询
 */
public class DBQuery 
    public String Request()
        return "数据库查询完毕";
    

使用类:

public class Client 
    public static void main(String[] args) 
        /**
         * 创建增强类对象
         */
        Enhancer enhancer = new Enhancer();

        /**
         * 创建增强类的父类对象
         */
        enhancer.setSuperclass(DBQuery.class);

        /**
         * 创建拦截切入类
         */
        enhancer.setCallback(new DBQueryCglibMethodInterceptor());

        /**
         * 创建代理对象
         */
        DBQuery dbQueryProxy = (DBQuery) enhancer.create();
        String result = dbQueryProxy.Request();
        System.out.println(result);
    

结果:

数据库查询完毕

使用CGLIB增强原有类的功能

MethodIntercptor实现类

/**
 * cglib代理逻辑切入类
 *  ---: intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
 *       o: 被代理类对象
 *       method: 要拦截的被代理类的方法
 *       objects:被代理类的方法参数
 *       methodyProxy: 要触发父类的方法对象
 */
public class CglibMethodInteceptor implements MethodInterceptor 
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable 
        System.out.println("插入前置通知");
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("插入后置通知");
        return object;
    

真实类:

/**
 * 使用cglib实现动态代理,不用创建接口
 */
public class HelloService 
    HelloService()
        System.out.println("HelloServie构造器");
    

    public final String sayOthers(String name)
        System.out.println("HelloService: sayOthers" +name);
        return null;
    

    public void sayHello()
        System.out.println("HelloService: sayHello");
    

    public void sayByeBye()
        System.out.println("HelloService: sayByeBye");
    

使用类:

public class Client 
    public static void main(String[] args) 
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\code");
        /**
         * 创建增强类对象
         */
        Enhancer enhancer = new Enhancer();

        /**
         * 创建需要增强的父类对象
         */
        enhancer.setSuperclass(HelloService.class);

        /**
         * 设置切入类对象
         */
        enhancer.setCallback(new CglibMethodInteceptor());

        /**
         * 生成代理对象
         */

        HelloService service = (HelloService) enhancer.create();
        service.sayHello();
        service.sayByeBye();
    

结果:

HelloServie构造器
插入前置通知
HelloService: sayHello
插入后置通知
插入前置通知
HelloService: sayByeBye
插入后置通知

以上是关于使用CGLIB实现动态代理的主要内容,如果未能解决你的问题,请参考以下文章

JDK动态代理与CGLIB动态代理

JDK动态代理与CGLIB动态代理

Cglib方法实现动态代理

jdk动态代理和cglib动态代理的区别

动态代理—— CGLIB代理原理

jdk动态代理和cglib动态代理底层实现原理详细解析(cglib动态代理篇)