动态代理之JDK原生代理和cglib代理区别

文章介绍了JDK原生代理和Cglib代理在Java中的实现方式和区别。JDK代理需要目标类实现接口,而Cglib则无需此要求,直接通过继承目标类来实现。JDK代理生成的是与目标类实现相同接口的代理类,而Cglib代理类是目标类的子类。Cglib适用于目标类没有实现接口的情况。
摘要由CSDN通过智能技术生成

动态代理之JDK原生代理和cglib代理区别

JDK代理实现

1,首先要实现JDK代理的先决条件为,代理类和目标类要实现相同的接口!!!这一点非常重要

JDK代理实现步骤:

(1)实现接口

​ 定义需要代理的方法

public interface House {
    /**
     * 租房*/
    void rent();
}

(2)定义目标类

​ 必须实现上面的接口

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Renter implements House{
    private String name;
    @Override
    public void rent() {
        System.err.println(name+"租到了房子……");
    }
}

(3)基于jdk代理实现动态代理(动态生成代理类)

​ 代码-固定,需要改变就是代理方法的增强

public class JdkProxy implements InvocationHandler {

    /**目标类对象*/
    private Object target;
    public JdkProxy(Object obj){
        this.target=obj;
    }

    /**
     * 1.代理的方法
     * 参数说明:
     * 1.proxy 代理对象
     * 2.method 代理的方法对象
     * 3.args 原方法的参数对象*/
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.err.println("我是中介,我来!");
        //执行原方法-目标类中的方法
        Object obj=method.invoke(target,args);
        System.err.println("我中介,租房任务完成!");
        return obj;
    }

    /**
     * 2.定义方法 实现代理类的生成*/
    public Object createProxy(){
        /*
        * 创建代理对象
        * 参数说明:
        * 1.类加载器
        * 2.目标类实现的接口
        * 3.InvocationHandler 接口的对象 方法增强的实现*/
        Object proxy=Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                this);
        return proxy;
    }
}

(4)测试运行

  @Test
    public void t1(){
        //1.目标类
        Renter renter = new Renter("siri");
        //2.生成代理类
        House house = (House) new JdkProxy(renter).createProxy();
        //3.执行租房方法
        house.rent();
    }

(5)执行结果

JDK代理的特点:

1.目标类 需要实现接口

2.目标类和代理类不能互相转换(代理类和目标类只是实现了相同的接口,但并没有直接关系)

问题,目标类没有实现接口,怎么办
这就需要cglib代理来干活了

Cglib代理

Cglib代理:CGLIB(Code Generation Library)是一个开源项目。

是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口

Cglib代理不对目标类有任何要求,可以直接实现目标类中的方法增强

Cglib代理实现步骤:

(1)依赖jar

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

(2)定义目标类

@Data
public class Staff {
    private String name;
    public void run(){
        System.err.println(name+"正在参加100米挑战赛!");
    }
}

(3)编写cglib代码

public class CglibProxy implements MethodInterceptor {
    /**
     * 1.代理类的方法 增强的处理
     * 参数说明:
     * 1.代理类对象
     * 2.目标方法
     * 3.目标方法的参数
     * 4.代理类中的目标方法*/
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //增强的处理
//        if(methodProxy.getSuperName().equals("run")) {
//        }
        System.err.println("加油!");
        //执行原方法 不要写错了  run
        Object obj = methodProxy.invokeSuper(o, objects);
        return obj;
    }

    /**
     * 2.生成代理类对象*/
    public <T> T createProxy(Class<T> target){
        Enhancer enhancer=new Enhancer();
        //代理类 继承的目标类☆☆☆☆☆
        enhancer.setSuperclass(target);
        //设置增强的方法 MethodInterceptor对象
        enhancer.setCallback(this);
        return (T)enhancer.create();
    }

}

(4)运行测试

    @Test
    public void t1(){
        //获取代理类对象 代理类继承目标类  代理目标中所有的方法
        Staff staff=new CglibProxy().createProxy(Staff.class);
        staff.setName("张三");
        staff.run();
    }

(5)结果

这里增强方法被执行了两次是因为,Staff类中的所有方法都被增强了,当然包括 staff.setName(“张三”)方法。

Cglib代理的特点:

1.代理类基层目标类

2.对目标类没有要求

JDK代理 VS Cglib代理

区别jdk代理Cglib代理
目标类必须实现接口没有要求
代理类代理类和目标类 实现相同的接口代理类继承目标类
区别jdk代理Cglib代理
目标类必须实现接口没有要求
代理类代理类和目标类 实现相同的接口代理类继承目标类
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值