首页 > 编程语言 >java动态代理和CGLIB

java动态代理和CGLIB

时间:2023-03-12 10:47:18浏览次数:44  
标签:java CGLIB jdk 代理 public cglib 动态 Hello

参考:https://www.jianshu.com/p/cbd4c1ad8a75

上一篇我们利用jdk的动态代理实现了一个简单的注解处理器,可以自动给一个button添加指定的监听器.

但是jdk的动态代理有一个不足之处,就是他代理的类必须实现了一个接口,如果我们要代理的类就是一个类,没有实现接口,

那么jdk的动态代理就无能无力了,这个时候我们需要用到一个更为强大的工具cglib,他可以动态给要代理的类生成一个子类

由子类代替父类完成工作,并作一定的功能增强.

下面我们举一个简单的例子,我又一个类,他只负责打招呼

public class Hello {

    public void sayHello(){
        System.out.println("hello,world");
    }
}

现在我在不改变这个类的基础上,想对他进行功能增强,应该怎么办?

肯定是使用代理啊,那Hello是个类,没有实现接口,我们只能用cglib,cglib是一个第三方的库,我们要先引进来

 <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>

 

接下来我们要定义一个方法过滤器,对sayHello进行增强,其中

methodProxy.invokeSuper(obj, args);就是调用原来hello里的sayHello
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class HelloMethodInterceptor implements MethodInterceptor {
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("log before method");
        Object result = methodProxy.invokeSuper(obj, args);
        System.out.println("log after method");
        return result;
    }
}

然后我们写一个例子,测试下效果

import net.sf.cglib.proxy.Enhancer;

public class HelloProxy {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Hello.class);
        enhancer.setCallback(new HelloMethodInterceptor());
        Hello proxy =(Hello) enhancer.create();
        proxy.sayHello();
    }
}

输出

log before method
hello,world
log after method

事实证明,cglib已经完美实现了我们想要的功能.

对比jdk的动态代理可以发现:

cglib的MethodInterceptor就相当于jdk动态代理中的InvocationHandler

cglib中的Enhancer就相当jdk动态代理中的Proxy

用法基本相同,只不过jdk动态代理基于接口实现,cglib是基于子类继承父类.

//代理的静态实现,更像Proxy.newInstance
        Hello proxy2 =(Hello) Enhancer.create(Hello.class, new HelloMethodInterceptor());
        proxy2.sayHello();

 

标签:java,CGLIB,jdk,代理,public,cglib,动态,Hello
From: https://www.cnblogs.com/wangbin2188/p/17207718.html

相关文章

  • 1_使用Mapper代理方式实现查询
     项目结构:注意文件路径和文件位置!!! 准备接口和mapper映射文件EmpMapper接口 packagecom.msb.mapper;importcom.msb.pojo.Emp;importjava.util.List;/***@Author:......
  • 1_使用Mapper代理方式实现查询
     项目结构:注意文件路径和文件位置!!! 准备接口和mapper映射文件EmpMapper接口 packagecom.msb.mapper;importcom.msb.pojo.Emp;importjava.util.List;/***@Author:......
  • 1_使用Mapper代理方式实现查询
    ​ 项目结构:注意文件路径和文件位置!!! 准备接口和mapper映射文件EmpMapper接口 packagecom.msb.mapper;importcom.msb.pojo.Emp;importjava.util.List;......
  • 1_使用Mapper代理方式实现查询
    ​ 项目结构:注意文件路径和文件位置!!! 准备接口和mapper映射文件EmpMapper接口 packagecom.msb.mapper;importcom.msb.pojo.Emp;importjava.util.List;......
  • Java基础四-异常处理/集合框架以及泛型
    异常的处理编写程序时,代码可能会重新啊运行错误或编译错误,为了处理问题可以使用异常机制异常包括错误类型,原因和位置异常的体系结构 如何进行异常处理java异常......
  • Java 分支结构——if-else(一)
    基本语法结构1:单分支条件判断:if格式:if(条件表达式){语句块;}说明:条件表达式必须是布尔表达式(关系表达式或逻辑表达式)或布尔变量。执行流程:首先判断条件表......
  • java学习日记20230310-类与对象
    类与对象类:自定义的数据类型:类是抽象的,概念的,代表一类事务,即是数据类型;对象(属性,行为:具体的实例):具体的,实际的,代表一个具体事物,即是实例;类是对象的模版,对象是类的一个个......
  • java 枚举类
    1.枚举概念:一个类中对象是可数的就是枚举2.枚举关键字:enum枚举类名3.枚举的常用方法:获取枚举值 3.1枚举类名称.对象名称3.2枚举类名称.values......
  • Java ConcurrentModificationException异常原因和解决方法
    场景对ArrayList在迭代的时候如果同时对其进行修改就会抛出java.util.ConcurrentModificationException异常。出现异常的代码://删除非此退货单对应的货位f......
  • java的数据和表达式
    一、基本语法元素1.空白和注释及语句(1)空白:换行符、回车符、空格键、水平定位键(Tab)编译器会忽略掉多余的空白作用:增加程序的易读性(2)注释:主要作用是将代码解释其功......