我正在以编程方式实现Spring AOP。 我创建了一个生成AOP Object.class代理的简单工厂类 使用给定的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 XML配置:
<bean id="simpleMethodInterceptor" class="...SimpleMethodInterceptor"/>
<bean id="objectAOPProxyFactoryBean" class="...AOPProxyFactoryBean">
<property name="methodInterceptors">
<list>
<ref bean="simpleMethodInterceptor"/>
</list>
</property>
</bean>
在文档here中 你可以阅读以下关于addAdvice(建议建议):'...请注意,给定的建议将适用于代理上的所有调用,甚至是toString()方法!...' < / p>
所以,我希望得到对SimpleMethodInterceptor拦截的Object.class方法的所有调用。
测试:
@Test
public void aopTest() {
Object o = (Object) applicationContext.getBean("objectAOPProxyFactoryBean");
o.toString();
o.equals(o);
o.getClass();
}
给出了这个输出:
SimpleMethodInterceptor:toString
似乎只有toString()方法被拦截了。知道为什么吗?
答案 0 :(得分:2)
奇。这对我来说似乎是个错误。我无法解释为什么,但我有一个可能的解决方法。创建一个接口并在那里重新定义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();
}
现在它将打印equals和hashCode。所以我认为行为是它不拦截对仅在Object上定义的方法的调用。并且toString被视为一种特殊情况。