我在用编程方式实现Spring。我创建了一个简单的工厂类,它使用给定的Object.class列表生成AOP MethodInterceptors代理:
public class AOPProxyFactoryBean implements FactoryBean<Object> {
private List<MethodInterceptor> methodInterceptors = new ArrayList<MethodInterceptor>();
public Object getObject() throws Exception {
Object o = new Object();
ProxyFactory proxyFactory = new ProxyFactory(o);
for (MethodInterceptor methodInterceptor : methodInterceptors) {
proxyFactory.addAdvice(methodInterceptor);
}
return proxyFactory.getProxy();
}
public Class<?> getObjectType() {
return Object.class;
}
public boolean isSingleton() {
return false;
}
public void setMethodInterceptors(List<MethodInterceptor> methodInterceptors) {
this.methodInterceptors = methodInterceptors;
}一个简单的拦截器:
public class SimpleMethodInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("SimpleMethodInterceptor: " + invocation.getMethod().getName());
return invocation.proceed();
}
}Spring配置:
<bean id="simpleMethodInterceptor" class="...SimpleMethodInterceptor"/>
<bean id="objectAOPProxyFactoryBean" class="...AOPProxyFactoryBean">
<property name="methodInterceptors">
<list>
<ref bean="simpleMethodInterceptor"/>
</list>
</property>
</bean>在docs 这里中,您可以阅读关于addAdvice(建议建议)的以下内容:请注意,给定的通知将应用于代理上的所有调用,甚至适用于toString()方法!
因此,我期望得到对Object.class方法的所有调用,这些调用被SimpleMethodInterceptor截获。
测试:
@Test
public void aopTest() {
Object o = (Object) applicationContext.getBean("objectAOPProxyFactoryBean");
o.toString();
o.equals(o);
o.getClass();
}给出这个输出:
SimpleMethodInterceptor: toString
似乎只有toString()方法被截获。知道为什么吗?
发布于 2012-07-04 21:33:55
很奇怪。对我来说好像是个虫子。我无法确切地解释原因,但我有一个可能的解决办法。创建一个接口并在那里重新定义equals和hashCode:
public interface MadeUpInterface {
@Override
public boolean equals(Object obj);
@Override
public int hashCode();
}从代理工厂返回实现该接口的实例。
public Object getObject() throws Exception {
Object o = new MadeUpInterface() {};
ProxyFactory proxyFactory = new ProxyFactory(o);
for (MethodInterceptor methodInterceptor : methodInterceptors) {
proxyFactory.addAdvice(methodInterceptor);
}
return proxyFactory.getProxy();
}现在,它将打印等于和hashCode。因此,我认为其行为是,它不拦截对仅在对象上定义的方法的调用。toString被视为特例。
https://stackoverflow.com/questions/10928559
复制相似问题