JDK动态代理说明
2011-06-23 21:22
295 查看
如果我们想实现类似AOP的思想,自己写代码用代理或叫装饰模式也是可以实现的,但这样我们就面临必须给每个需要被装饰(我们暂时就叫它装饰吧)的接口写装饰子类,通过添加自己需要的特定功能并委托实体接口子类完成本体行为。这样我们需要写很多代码,而且很多时候都是重复代码,当然用种种模式可以把重复代码消减到最少,但看起来还是不怎么完美。
这时候JDK的动态代理就其作用了,它帮我们减少了大量代码的编写工作,使我们可以将注意力放在我们需要添加的特定行为上。那JDK的动态代理又是如何完成的呢?它是通过动态继承基类Proxy并实现我们要代理的接口,将接口实现委托给InvocationHandler中的invoke, 将调用方法以参数形式传给invoke,同时InvocationHandler的子类持有真正的实体类对象以供方法调用。
JDK中动态代理就是代理模式的变体。如图
再看一例子:
上面的实现已经可以实现我们动态给某个方法添加其他功能了,但是它只能加一次,如果我们能以一种链化的动态代理,可以添加多层拦截那对实际应用可能更有效果,由此我们可以改变一下我们的设计,如图:
为了更好理解,看下例子。
再看下运行结果:
doBefore1
doBefore2
doBefore3
hello world
doAfter3
doAfter2
doAfter1
OK了,经过改造我们可以实现链化动态代理了,对于实际应用更能体现我们对各个层面上的切入
这时候JDK的动态代理就其作用了,它帮我们减少了大量代码的编写工作,使我们可以将注意力放在我们需要添加的特定行为上。那JDK的动态代理又是如何完成的呢?它是通过动态继承基类Proxy并实现我们要代理的接口,将接口实现委托给InvocationHandler中的invoke, 将调用方法以参数形式传给invoke,同时InvocationHandler的子类持有真正的实体类对象以供方法调用。
JDK中动态代理就是代理模式的变体。如图
再看一例子:
public interface Hello { public void say(); } public class HelloImpl implements Hello { public void say() { System.out.println("hello world"); } } public class ConcreteInvocationHandler implements InvocationHandler { private Object realObject; public ConcreteInvocationHandler(Hello realObject) { this.realObject = realObject; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before method operation"); method.invoke(realObject, new Object[0]); System.out.println("after method operation"); return null; } } public static void main(String[] args) { Hello hello = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class[] { Hello.class }, new ConcreteInvocationHandler(new HelloImpl())); hello.say(); }
上面的实现已经可以实现我们动态给某个方法添加其他功能了,但是它只能加一次,如果我们能以一种链化的动态代理,可以添加多层拦截那对实际应用可能更有效果,由此我们可以改变一下我们的设计,如图:
为了更好理解,看下例子。
public interface CustomInvocationHandler extends InvocationHandler { public void doBefore(); public void doAfter(); } public abstract class AbstractInvocationHandler implements CustomInvocationHandler { protected Object realObject; protected AbstractInvocationHandler successor; protected AbstractInvocationHandler(Object realObject) { this.realObject = realObject; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; doBefore(); if (this.successor == null) { result = method.invoke(this.realObject, args); } else { result = successor.invoke(proxy, method, args); } doAfter(); return result; } public void setSuccessor(AbstractInvocationHandler successor) { this.successor = successor; } } public class ConcreteInvocationHandler1 extends AbstractInvocationHandler { protected ConcreteInvocationHandler1(Object realObject) { super(realObject); } public void doAfter() { System.out.println("doAfter1"); } public void doBefore() { System.out.println("doBefore1"); } } public class ConcreteInvocationHandler2 extends AbstractInvocationHandler { protected ConcreteInvocationHandler2(Object realObject) { super(realObject); } public void doAfter() { System.out.println("doAfter2"); } public void doBefore() { System.out.println("doBefore2"); } } public class ConcreteInvocationHandler3 extends AbstractInvocationHandler { protected ConcreteInvocationHandler3(Object realObject) { super(realObject); } public void doAfter() { System.out.println("doAfter3"); } public void doBefore() { System.out.println("doBefore3"); } } public class TestLinkedProxy { public static void main(String[] args) { Hello hello = new HelloImpl(); ConcreteInvocationHandler1 h1 = new ConcreteInvocationHandler1(hello); ConcreteInvocationHandler2 h2 = new ConcreteInvocationHandler2(hello); ConcreteInvocationHandler3 h3 = new ConcreteInvocationHandler3(hello); h1.setSuccessor(h2); h2.setSuccessor(h3); Hello h = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class[] { Hello.class }, h1); h.say(); } }
再看下运行结果:
doBefore1
doBefore2
doBefore3
hello world
doAfter3
doAfter2
doAfter1
OK了,经过改造我们可以实现链化动态代理了,对于实际应用更能体现我们对各个层面上的切入
相关文章推荐
- jdk自带的动态代理说明
- JDK与Cglib实现的动态代理区别以及例子说明
- JDK动态代理
- 设计模式之Proxy(代理):模拟JDK的动态代理
- JDK动态代理与cglib
- 使用反射生成JDK动态代理---动态代理和AOP
- 深度剖析JDK动态代理机制
- 《精通Spring4.X企业应用开发实战》读后感第七章(AOP基础知识、jdk动态代理,CGLib动态代理)
- jdk 源码分析(21)java 动态代理和反射
- spring 动态代理如何决定使用jdk代理和cglib(网易面试题)
- 常用设计模式之动态代理1(JDK)
- jdk的动态代理和CGLIB的区别
- JDK动态代理实现原理
- JDK的动态代理原理
- JDK动态代理实现原理
- JDK的动态代理-升级版
- Java动态代理之JDK动态代理和CGLib动态代理
- JDK动态代理实现原理(转)
- spring AOP出现拦截无效的情况(一般是jdk动态代理失败)
- jdk动态代理 写得非常好转载下