如果按照最原始的方式来实现java的代理模式,就是一个类生成一个代理接口类,针对对应方法都嵌入想要处理的前置通知和后置通知。这样的坏处是每个类都会生成一个代理类,会浪费资源。jdk原生的Proxy代理类,从jvm层面上解决接口代理模式的问题。
目标接口
package com.proxy; /** * Created by Dongbin.Yu on 2015/11/18. */ public interface Subject { public void handle(); }
目标类
package com.proxy; /** * @author dongbin.yu * @version 1.0.0 * @since 2015/11/18 */ public class SubjectImpl implements Subject { @Override public void handle() { System.out.println("hello world!"); } }
package com.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * @author dongbin.yu * @version 1.0.0 * @since 2015/11/18 */ public class DelegateProxy implements InvocationHandler { private Object target; //目标类 public DelegateProxy(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("start proxy"); Object result = method.invoke(target, args); System.out.println("end proxy"); return result; } }
package com.proxy; import java.lang.reflect.Proxy; /** * @author dongbin.yu * @version 1.0.0 * @since 2015/11/18 */ public class MainProxy { public static void main(String[] args) { Subject subject = new SubjectImpl(); DelegateProxy delegateProxy = new DelegateProxy(subject); Subject subjectProxy = (Subject)Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), delegateProxy); --这个动态生成的代理类也可以由handle来提供。 subjectProxy.handle(); } }
调用的地方需要将这个handle处理器注册到这个代理类里面。大胆的猜测jvm虚拟机的内部其实动态的生成代理类的字节码,使用相同的ClassLoader和Interface来唯一绑定这个代理类。这种方式其实也面临着方法区动态生成的代理类的回收情形。