使用ProxyFactory实现编程式Spring AOP

时间:2012-06-07 08:48:16

标签: java spring aop spring-aop proxyfactory

我正在以编程方式实现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()方法被拦截了。知道为什么吗?

1 个答案:

答案 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被视为一种特殊情况。