JAVA代理模式 - 动态代理(三)
核心思想
A. 用于增强一些方法,在方法执行前后做任何你想做的事情,实现无侵入式的代码扩展; B. 可以用作远程调用这样的场景; C. 每一个动态代理类都必须要实现InvocationHandler这个接口,实现invoke方法,动态代理类只能代理接口(不支持抽象类); D. 一定会用到的类或者接口是:InvocationHandler(Interface)、Proxy(Class); E. 代理类与普通类的唯一区别就是,其字节码是由 JVM 在运行时动态生成的而非预存在于任何一个 .class 文件中; F. 每次生成动态代理类对象时都需要指定一个类装载器对象,指定为和目标对象同一个类加载器; G. 生成的代理类为public final,不能被继承,类名:格式是“$ProxyN”,N是逐一递增的数字。
实现步骤
1.定义一个接口; 2.定义一个该接口的真实实现类; 3.定义一个Handler类,该类实现InvocationHandler接口,并实现invoke方法,在该类中可以定义获取代理对象的方法,还可以把该方法在客户端类中进行定义。
示例代码
1.定义一个接口TheUser.java package com.rocky.learn.l003.t3; public interface TheUser { public abstract String say(); } 2.定义一个该接口的真实实现类 TheUserImpl.java package com.rocky.learn.l003.t3; public class TheUserImpl implements TheUser { @Override public String say() { return "Hello world, And Im testing the DYNAMIC-PROXY."; } } 3.定义一个Handler类,该类实现InvocationHandler接口,并实现invoke方法,在该类中可以定义获取代理对象的方法,还可以把该方法在客户端类中进行定义MyInvocationHandler.java package com.rocky.learn.l003.t3; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class MyInvocationHandler implements InvocationHandler { private Object target; //The real object public MyInvocationHandler(Object target) { super(); this.target = target; } @Override public Object invoke(Object object, Method method, Object[] args) throws Throwable { System.out.println(">BEFORE"); Object result = method.invoke(target, args); System.out.println(result); System.out.println(">END."); return result; } public Object getProxy() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } }
如何调用
package com.rocky.learn.l003.t3; public class Test { public static void main(String[] args) { MyInvocationHandler handler = new MyInvocationHandler(new TheUserImpl()); TheUser proxy = (TheUser) handler.getProxy(); proxy.say(); } }