jdk Dynamic Proxy 动态代理 - 高飞网
231 人阅读

jdk Dynamic Proxy 动态代理

2017-07-28 02:09:46

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

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

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

应用:spring中的AOP。

下面是示例代码:

  1. public interface WriteService {  
  2.     public void write();  
  3. }  
  4.   
  5. public interface ReadService {  
  6.     //阅读  
  7.     public void read();  
  8. }  
  9.   
  10. public class LearnServiceImpl implements ReadService,WriteService {  
  11.   
  12.     @Override  
  13.     public void read() {  
  14.         System.out.println("read()...");  
  15.     }  
  16.   
  17.     @Override  
  18.     public void write() {  
  19.         System.out.println("write()...");  
  20.     }  
  21.   
  22. }  
  23.   
  24. //动态代码类,实现InvocationHandler  
  25. public class DynamicProxy implements InvocationHandler {  
  26.     private Object target;  
  27.   
  28.     public DynamicProxy(Object target) {  
  29.         this.target = target;  
  30.     }  
  31.   
  32.     public Object createDynamicProxy() {  
  33.         return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);  
  34.     }  
  35.   
  36.     @Override  
  37.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  38.         System.out.println("before "+method.getName()+"()...");  
  39.         Object result = method.invoke(this.target, args);  
  40.         System.out.println("after "+method.getName()+"()...");  
  41.         return result;  
  42.     }  
  43.   
  44. }  
  45.   
  46. public class DynamicProxyDemo {  
  47.     public static void main(String[] args) {  
  48.         LearnServiceImpl ro = new LearnServiceImpl();  
  49.         ReadService proxy0 = (ReadService) new DynamicProxy(ro).createDynamicProxy();  
  50.         proxy0.read();  
  51.         System.out.println("代理对象:" + proxy0.getClass().getName());  
  52.         System.out.println("===========");  
  53.         WriteService proxy1 = (WriteService) new DynamicProxy(ro).createDynamicProxy();  
  54.         proxy1.write();  
  55.         System.out.println("代理对象:" + proxy1.getClass().getName());  
  56.     }  

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

运行结果:
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
23.20.162.200