回答
类java.lang.reflect.Proxy
允许您通过处理InvocationHandler
中的方法调用来动态实现接口。它被认为是Java的反射工具的一部分,但与字节码生成无关。
关于使用Proxy类,Sun有a tutorial。 Google helps, too.
一个用例是hibernate--它为您提供了实现您的模型类接口的对象,但是在getters和setters下面存在与db相关的代码。即你使用它们就好像它们只是简单的POJO一样,但实际上有很多事情正在掩盖之中。
例如 - 你只需调用lazily加载的属性的getter,但真正的属性(可能是整个大对象结构)从数据库中获取。
您应该检查cglib库以获取更多信息。
甲动态代理类是实现在运行时指定的 接口的列表,使得通过对类的一个实例的接口 一个将被编码和 方法调用调度到另一个类通过统一的界面对象。它可以是 ,用于为接口列表创建类型安全的代理对象 ,无需预先生成代理类。动态代理 类对于需要提供 类型安全的对调用接口API的对象的反射调度的应用程序或库很有用。
好的答案,这个事情的一个很好的例子是Spring Remoting,它内置了HTTP,RMI,EJB和JMS的代理功能。 – Robin 2009-06-01 13:39:53
我只是想出了一个动态代理一个有趣的使用。
我们遇到了一些与非关键服务相关的服务,这些服务与另一个相关服务结合在一起,并且希望探索在相关服务不可用时的容错方式。
所以我写了一个LoadSheddingProxy需要两个代表 - 一个是'正常'服务的远程impl(在JNDI查找之后)。另一个对象是一个“虚拟”卸载impl。围绕每个方法调用的简单逻辑可以捕获超时并在重试之前转向虚拟机一段时间。下面是我如何使用它:
// This is part of your ServiceLocator class
public static MyServiceInterface getMyService() throws Exception
{
MyServiceInterface loadShedder = new MyServiceInterface() {
public Thingy[] getThingys(Stuff[] whatever) throws Exception {
return new Thingy[0];
}
//... etc - basically a dummy version of your service goes here
}
Context ctx = JndiUtil.getJNDIContext(MY_CLUSTER);
try {
MyServiceInterface impl = ((MyServiceHome) PortableRemoteObject.narrow(
ctx.lookup(MyServiceHome.JNDI_NAME),
MyServiceHome.class)).create();
// Here's where the proxy comes in
return (MyService) Proxy.newProxyInstance(
MyServiceHome.class.getClassLoader(),
new Class[] { MyServiceInterface.class },
new LoadSheddingProxy(MyServiceHome.JNDI_NAME, impl, loadShedder, 60000)); // 10 minute retry
} catch (RemoteException e) { // If we can't even look up the service we can fail by shedding load too
logger.warn("Shedding load");
return loadShedder;
} finally {
if (ctx != null) {
ctx.close();
}
}
}
而这里的代理:
public class LoadSheddingProxy implements InvocationHandler {
static final Logger logger = ApplicationLogger.getLogger(LoadSheddingProxy.class);
Object primaryImpl, loadDumpingImpl;
long retry;
String serviceName;
// map is static because we may have many instances of a proxy around repeatedly looked-up remote objects
static final Map<String, Long> servicesLastTimedOut = new HashMap<String, Long>();
public LoadSheddingProxy(String serviceName, Object primaryImpl, Object loadDumpingImpl, long retry)
{
this.serviceName = serviceName;
this.primaryImpl = primaryImpl;
this.loadDumpingImpl = loadDumpingImpl;
this.retry = retry;
}
public Object invoke(Object obj, Method m, Object[] args) throws Throwable
{
try
{
if (!servicesLastTimedOut.containsKey(serviceName) || timeToRetry()) {
Object ret = m.invoke(primaryImpl, args);
servicesLastTimedOut.remove(serviceName);
return ret;
}
return m.invoke(loadDumpingImpl, args);
}
catch (InvocationTargetException e)
{
Throwable targetException = e.getTargetException();
// DETECT TIMEOUT HERE SOMEHOW - not sure this is the way to do it???
if (targetException instanceof RemoteException) {
servicesLastTimedOut.put(serviceName, Long.valueOf(System.currentTimeMillis()));
}
throw targetException;
}
}
private boolean timeToRetry() {
long lastFailedAt = servicesLastTimedOut.get(serviceName).longValue();
return (System.currentTimeMillis() - lastFailedAt) > retry;
}
}
- 1. 什么是无限迭代器?为什么要使用它?
- 2. 什么是python中的类,它做什么,它为什么需要它?
- 3. 春天 - 它是什么,为什么我想要使用它?
- 4. 什么是静态库,什么是动态库,有什么区别,什么是更好的使用,为什么?
- 5. 什么是检查点节点HDFS?为什么要使用它?
- 6. 什么是片段URL以及为什么要使用它
- 7. 什么是MQ,我为什么要使用它?
- 8. 什么是SEAM框架,我为什么要使用它?
- 9. 什么是C#中的字段,我为什么要使用它?
- 10. 什么是.inc以及为什么要使用它?
- 11. 什么是断言?你为什么要使用它们?
- 12. 什么是React Native?我为什么要使用它?
- 13. 什么是TDS协议版本8.0,为什么要使用它?
- 14. 什么是语义标记,为什么要使用它?
- 15. EntityManager.flush是做什么的,为什么我需要使用它?
- 16. 什么是PDO,我为什么要使用它?
- 17. 什么是依赖注入,为什么要使用它?
- 18. Bonjour是什么,我为什么要使用它?
- 19. GWT.create是什么意思,为什么要使用它?
- 20. 为什么我需要Iterator接口,为什么要使用它?
- 21. 什么是代理类
- 22. 什么是JsonUtility,为什么我的代码使用它?
- 23. 什么是使用类动态
- 24. 什么是树摇动,为什么我需要它?
- 25. 什么是基类构造函数,我为什么要使用它? (带示例)
- 26. 什么是反向代理,为什么我应该使用Node.JS?
- 27. 为什么要使用websocket,使用它有什么好处?
- 28. 什么是WCF代理,它们有什么用途?
- 29. 科尔多瓦遥测,它是什么,为什么使用它?
- 30. 什么是Clojure的同花顺,为什么它是必要的?
好的解释在这里https://opencredo.com/dynamic-proxies-java/ – Bala 2016-06-28 13:41:37