|
| 1 | +package io.github.dunwu.javacore.reflect; |
| 2 | + |
| 3 | +import java.lang.reflect.InvocationHandler; |
| 4 | +import java.lang.reflect.Method; |
| 5 | +import java.lang.reflect.Proxy; |
| 6 | + |
| 7 | +/** |
| 8 | + * 动态代理示例 |
| 9 | + * @author Zhang Peng |
| 10 | + */ |
| 11 | +public class InvocationHandlerDemo implements InvocationHandler { |
| 12 | + |
| 13 | + public interface Subject { |
| 14 | + |
| 15 | + void hello(String str); |
| 16 | + |
| 17 | + String bye(); |
| 18 | + } |
| 19 | + |
| 20 | + public static class RealSubject implements Subject { |
| 21 | + |
| 22 | + @Override |
| 23 | + public void hello(String str) { |
| 24 | + System.out.println("Hello " + str); |
| 25 | + } |
| 26 | + |
| 27 | + @Override |
| 28 | + public String bye() { |
| 29 | + System.out.println("Goodbye"); |
| 30 | + return "Over"; |
| 31 | + } |
| 32 | + } |
| 33 | + |
| 34 | + // 这个就是我们要代理的真实对象 |
| 35 | + private Object subject; |
| 36 | + |
| 37 | + // 构造方法,给我们要代理的真实对象赋初值 |
| 38 | + public InvocationHandlerDemo(Object subject) { |
| 39 | + this.subject = subject; |
| 40 | + } |
| 41 | + |
| 42 | + @Override |
| 43 | + public Object invoke(Object object, Method method, Object[] args) |
| 44 | + throws Throwable { |
| 45 | + // 在代理真实对象前我们可以添加一些自己的操作 |
| 46 | + System.out.println("Before method"); |
| 47 | + |
| 48 | + System.out.println("Call Method: " + method); |
| 49 | + |
| 50 | + // 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用 |
| 51 | + Object obj = method.invoke(subject, args); |
| 52 | + |
| 53 | + // 在代理真实对象后我们也可以添加一些自己的操作 |
| 54 | + System.out.println("After method"); |
| 55 | + System.out.println(); |
| 56 | + |
| 57 | + return obj; |
| 58 | + } |
| 59 | + |
| 60 | + public static void main(String[] args) { |
| 61 | + // 我们要代理的真实对象 |
| 62 | + Subject realSubject = new RealSubject(); |
| 63 | + |
| 64 | + // 我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的 |
| 65 | + InvocationHandler handler = new InvocationHandlerDemo(realSubject); |
| 66 | + |
| 67 | + /* |
| 68 | + * 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数 |
| 69 | + * 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象 |
| 70 | + * 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了 |
| 71 | + * 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上 |
| 72 | + */ |
| 73 | + Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject |
| 74 | + .getClass().getInterfaces(), handler); |
| 75 | + |
| 76 | + System.out.println(subject.getClass().getName()); |
| 77 | + subject.hello("World"); |
| 78 | + String result = subject.bye(); |
| 79 | + System.out.println("Result is: " + result); |
| 80 | + } |
| 81 | +} |
0 commit comments