动态代理

本文深入探讨了动态代理的概念及其实现方式,对比静态代理,介绍了JDK动态代理与CGLIB的不同应用场景,并通过示例代码展示了如何使用JDK动态代理实现对象的方法调用拦截。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇我们讲了静态代理,静态代理拥有好多好处,但是带来的缺点也很烦,于是出现了动态代理。

  1. 动态代理和静态代理的角色是一样的
  2. 动态代理的代理类是动态生成的
  3. 分为两类——类基于接口动态代理和基于类的动态代理
    (1)基于接口动态代理——jdk动态代理
    (2)基于类的动态代理——cglib
    现在javasist来动态代理(Struts2和mybatis等都可以发现这个jar包)
    百度javasist发现

    javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

这里我们讲jdk动态代理,了解一种就可以触类旁通
jdk动态代理——Proxy类和InvocationHandler
实现InvocationHandler接口


查看Api InvocationHandler的定义
InvocationHandler 是代理实例的调用处理程序实现的接口。

每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。


文字比较绕口,要看的话可以查阅API,我们还是直接看代码吧,还是通过中介找房子这个案例
Rent.java

public interface Rent {
    public void rent();
}

Host.java

public class Host implements Rent{
    public void rent(){
        System.out.println("房屋出租");  
    }
}

代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyInvocationhandler implements InvocationHandler{
    private  Object  target;
    public void setTarget(Object target) {
        this.target = target;
    }
    //生成代理类
    public Object  getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), 
                target.getClass().getInterfaces(), this);//最后一个参数是实现了InvocationHandler的类
    }
    //proxy是代理类,method代理类的调用处理程序方法的对象
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)`这里写代码片`
            throws Throwable {
        Object  result=method.invoke(target, args);//反射的知识。相当于rent调用方法  args是参数
        return result;
    }

}

Client.java

public class Client {
    public static void main(String[] args) {
        Host host=new Host();
        ProxyInvocationhandler pi=new ProxyInvocationhandler();
        pi.setTarget(host);
        Rent proxy=(Rent)pi.getProxy();
        proxy.rent(); 
    }
}

以上发现代理中

 private  Object  target;
    public void setTarget(Object target) {
        this.target = target;
    }

其实JDK动态代理严格应该是 ,基于接口

private  Rent  rent;
    public void setRent(Rent rent){
        this.rent = rent;
    }

所以是动态代理 消除了静态代理的坏处。


JDK动态代理只能针对实现了接口的类生成代理。
cglib代理是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。

如果目标对象没有实现接口,则默认会采用CGLIB代理;

如果目标对象实现了接口,可以强制使用CGLIB实现代理

AOP包括切面(aspect)、通知(advice)、连接点(joinpoint),实现方式就是通过对目标对象的代理在连接点前后加入通知,完成统一的切面操作。

通过讲解代理为下面的spring aop做准备。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值