引入
相较于静态代理模式,所有的方法动态生成。
这里介绍基于JDK的方式实现动态代理。
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class ProxyInvocationHandler implements InvocationHandler { private Object target;
public void setTarget(Object target) { this.target = target; }
public Object getProxy() { return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName()); Object result = method.invoke(target, args); return result; }
private void log(String msg) { System.out.println("[Log] " + msg); } }
|
Proxy
返回代理类,需要传入:
- 当前作为Proxy的
Class加载器
.
- 需要代理的
对象的接口
。
- 自定义的InvocationHandler,实现了
InvocationHandler
接口。
1 2 3
| public Object getProxy() { return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); }
|
InvocationHandler
唤起事务处理。
1 2 3 4 5 6
| @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName()); Object result = method.invoke(target, args); return result; }
|
实现了InvocationHandler
,需要重写invoke
方法。
使用反射的方法执行method.invoke
传入
- 被代理的接口(target)
- 执行时的形参(args)
在唤起执行方法前后,可以加入自定义的事务处理。
自定义
可以实现将一个ProxyInvocationHandler
分成一个CustomProxy
和一个CustomInvocationHandler
。
CustomInvocationHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class CustomInvocationHandler implements InvocationHandler {
private IndexService indexService;
public CustomInvocationHandler(IndexService indexService) { this.indexService = indexService; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { logBefore(method.getName()); Object res = method.invoke(indexService, args); logAfter(indexService.getClass().getName()); return res; }
private void logBefore(String msg) { System.out.println("[Log] " + msg); }
private void logAfter(String msg) { System.out.println("[Log] " + msg + "has been done!"); } }
|
CustomProxy
1 2 3 4 5 6
| public class CustomProxy {
public Object getProxy(IndexService indexService, InvocationHandler invocationHandler) { return Proxy.newProxyInstance(this.getClass().getClassLoader(), indexService.getClass().getInterfaces(), invocationHandler); } }
|
Client
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class CustomClient { public static void main(String[] args) { IndexService indexService = new IndexServiceImpl(); CustomInvocationHandler customInvocationHandler = new CustomInvocationHandler(indexService); CustomProxy customProxy = new CustomProxy(); IndexService proxy = (IndexService) customProxy.getProxy(indexService, customInvocationHandler); proxy.add(); } }
|
Proxy
与InvocationHandler
可以分离。
InvocationHandler
必须要传需要代理的接口。
Proxy
必须要传需要代理的接口,以及自定义的Handler
。
问题
Proxy
与InvocationHandler
可以解藕,但是他们都需要被代理的接口。
进行接口实现接口的设计?
InvocationHandler
中实现了invoke
后其中传的Proxy
的作用?