jdk Dynamic Proxy 动态代理

2018年12月25日 17:20 阅读 831 Java JDK

说到动态代理,首先介绍下静态代理,静态代理是指首先有一组对外开放的接口,已知A类实现了此类接口,那么现在有一个代理类B同样实现了接口中的方法,这样在方法中调用被代理类A中相应的方法,在调用前后,可以加上一些处理代码,如日记记录,事务开启关闭等等。

而动态代理,关键一点就是动态,即将这种代理关系,延迟到jvm运行是来实现。相同需要一组对外接口,代理类实现InvocationHandler接口并实现其中的方法invoke(),然后用Proxy.newProxyInstance()创建代理类。

显然动态代理类有更好的灵活性,虽然为次而损失了一定的性能(其中存在大量的反射应用)。注意,代理的是接口不是类更不是抽象类。

应用:spring中的AOP。

下面是示例代码:


public interface WriteService {  
    public void write();  
}  
  
public interface ReadService {  
    //阅读  
    public void read();  
}  
  
public class LearnServiceImpl implements ReadService,WriteService {  
  
    @Override  
    public void read() {  
        System.out.println("read()...");  
    }  
  
    @Override  
    public void write() {  
        System.out.println("write()...");  
    }  
  
}  
  
//动态代码类,实现InvocationHandler  
public class DynamicProxy implements InvocationHandler {  
    private Object target;  
  
    public DynamicProxy(Object target) {  
        this.target = target;  
    }  
  
    public Object createDynamicProxy() {  
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);  
    }  
  
    @Override  
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
        System.out.println("before "+method.getName()+"()...");  
        Object result = method.invoke(this.target, args);  
        System.out.println("after "+method.getName()+"()...");  
        return result;  
    }  
  
}  
  
public class DynamicProxyDemo {  
    public static void main(String[] args) {  
        LearnServiceImpl ro = new LearnServiceImpl();  
        ReadService proxy0 = (ReadService) new DynamicProxy(ro).createDynamicProxy();  
        proxy0.read();  
        System.out.println("代理对象:" + proxy0.getClass().getName());  
        System.out.println("===========");  
        WriteService proxy1 = (WriteService) new DynamicProxy(ro).createDynamicProxy();  
        proxy1.write();  
        System.out.println("代理对象:" + proxy1.getClass().getName());  
    }  
}  


动态代理可以在不改变原来已有代码结构的情况下,对原来“真实方法”进行扩展,增强其功能,并且可以达到控制被代理对象的行为
的目的。

运行结果:
before read()...
read()...
after read()...
代理对象:$Proxy0
===========
before write()...
write()...
after write()...
代理对象:$Proxy0

作为一个Dynamic Proxy,必须满足三个条件:
1.实现了InvocationHandler接口,实现接口中定义的invoke方法
2.包含接口实现类的实例

3.通过Proxy.newProxyInstance()方法Proxy与接口之间的绑定。

类图:

stone

问下,这文章是原创还是转载?
发布于:2017-09-05 11:49:40.0