动态代理

来源:互联网 发布:战略发展部 知乎 编辑:程序博客网 时间:2024/06/05 07:30

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

  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做准备。

原创粉丝点击