Java动态代理机制提供了一种有趣的方式来创建代理实例。 不过,创建动态代理的步骤有些繁琐,请考虑将代理用于审核服务实例的方法调用所花费的时间–
public interface InventoryService {public Inventory create(Inventory inventory);public List<Inventory> list();public Inventory findByVin(String vin);public Inventory update(Inventory inventory);public boolean delete(Long id);public Inventory compositeUpdateService(String vin, String newMake);
}
为该接口的实例创建动态代理的步骤如下:
1.创建一个java.lang.reflect.InvocationHandler的实例,它将负责代表实际服务实例处理方法调用,用于审核的示例Invocation处理程序如下:
...
public class AuditProxy implements java.lang.reflect.InvocationHandler {private Object obj;public static Object newInstance(Object obj) {return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new AuditProxy(obj));}private AuditProxy(Object obj) {this.obj = obj;}public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {Object result;try {logger.info("before method " + m.getName());long start = System.nanoTime();result = m.invoke(obj, args);long end = System.nanoTime();logger.info(String.format("%s took %d ns", m.getName(), (end-start)) );} catch (InvocationTargetException e) {throw e.getTargetException(); } catch (Exception e) {throw new RuntimeException("unexpected invocation exception: " + e.getMessage());} finally {logger.info("after method " + m.getName());}return result;}
}
2.创建InventoryService实例时,返回一个代理,在本例中为AuditProxy,它构成InventoryService的实例,使用UML可以更好地解释该代理:
这就是它在代码中的样子:
InventoryService inventoryService = (InventoryService)AuditProxy.newInstance(new DefaultInventoryService());
现在,对库存服务的任何调用都将通过AuditProxy实例进行,该实例将在将实际方法调用委派给InventoryService实例的同时测量方法花费的时间。
那么代理用于:
1. Spring AOP广泛使用它–它在内部为不同的AOP构造创建动态代理
2.如本例所示,对于任何类别的装饰,尽管AOP绝对适合这种用例 3.对于需要支持基于接口和注释的功能的任何框架–甚至不需要真实的代理实例,动态代理可以基于通过注释提供的一些元数据来重新创建接口的预期行为。
参考: all和杂物博客上的JCG合作伙伴 Biju Kunjummen 创建了Java动态代理 。
翻译自: https://www.javacodegeeks.com/2012/08/creating-java-dynamic-proxy.html