如何拦截具有标准java特性的方法调用(无AspectJ等)?
我想拦截所有的方法调用一些类MyClass能够对一些setter-invocations作出反应。
我试图使用dynamic代理,但据我所知,这只适用于实现一些接口的类。 但MyClass没有这样的接口。
除了实现一个包装类之外,还有其他的方式,把所有的调用委托给一个成员,这个成员是MyClass的一个实例,或者是使用AOP的另一个实例?
正如你注意到的,你不能使用JDKdynamic代理(无界面),但是使用Spring和CGLIB(Spring附带的JAR),你可以执行以下操作:
public class Foo { public void setBar() { throw new UnsupportedOperationException("should not go here"); } public void redirected() { System.out.println("Yiha"); } } Foo foo = new Foo(); ProxyFactory pf = new ProxyFactory(foo); pf.addAdvice(new MethodInterceptor() { public Object invoke(MethodInvocation mi) throws Throwable { if (mi.getMethod().getName().startsWith("set")) { Method redirect = mi.getThis().getClass().getMethod("redirected"); redirect.invoke(mi.getThis()); } return null; } }); Foo proxy = (Foo) pf.getProxy(); proxy.setBar(); // prints "Yiha"
如果你准备做一些非常难看的事情,请看看:
http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/
基本上debugging器接口应该允许你像一个debugging器,因此拦截调用。 请记住,我认为这是一个非常糟糕的主意,但你问是否有可能。
Java没有任何方法拦截的实际语言function(不确定任何静态语言)
我有点像Nick的使用debugging器接口的想法,这只是意味着什么。
我认为你需要的简短答案是:没有没有一种方法可以拦截Java中的方法调用,而无需使用代理或包装器实际replace类。
注意:AOP库只是自动发生这种情况。
我刚刚为此目的开发了一个小框架。 你可以在http://code.google.com/p/java-interceptor/查看(使用svn来检出)。;
一些Java大师可能会对此表示担忧,但是我完全避免了原始types和设置者,取得了一些成功。 我的课堂看起来像这样:
class Employee extends SmartPojo { public SmartString name; public SmartInt age; }
你会注意到两件事:1.一切都是公开的。 2.没有构造函数。
在SmartPojo中发生了奇迹,它search任何实现“智能”接口的字段并对其进行初始化。 由于这不是原始的(也没有最终的类),所以我可以在一个地方为我的模型中的任何地方的所有字段添加set()和get()方法。 所以不再有二传手/二手车的浪费了,添加通知(也在一个地方)是非常简单的,等等。
诚然,这已经不是一个豌豆了,在大多数情况下这不是一个豌豆,但是我发现这些旧的想法限制了我,而不是他们的帮助。 因人而异。
AspectJ没有太多的魔力。 你可以写你自己的代理。 http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html似乎是一个很好的起点。;
-
为什么你的类不能实现一个接口? 你可以从它中提取一些包含你想拦截的所有方法的接口,并且很容易地使用dynamic代理机制。 使用接口而不是类进行编码也是一个很好的编程习惯。
-
您可以使用Spring框架和Spring AOPfunction(使用内部的dynamic代理)来执行此操作。 你只需要在configuration文件中将你的类定义为一个Spring bean,并且你的类的客户端必须从Spring应用程序上下文中获取它的实例,或者自动作为一个依赖项(通过定义setMyClass(MyClass mc)方法)。 从那里你可以很容易地定义一个截取所有方法调用这个类的方面。
为了拦截java方法调用,一个AspectJ是很好的使用工具。 通过它可以有效地拦截方法调用,执行等。 我使用拦截java方法调用的相同工具。 我们可以使用切入点ansd方面来拦截任何的java方法调用。 仅仅用于阅读这些信息