【问题标题】:Implementing programmatic Spring AOP with ProxyFactory使用 ProxyFactory 实现程序化 Spring AOP
【发布时间】:2012-06-07 08:48:15
【问题描述】:

我正在尝试以编程方式实现 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(Advice advice) 的内容:'...请注意,给定的建议将适用于代理上的所有调用,甚至适用于 toString() 方法!...'

所以,我希望所有对 Object.class 方法的调用都被 SimpleMethodInterceptor 拦截。

测试:

@Test
public void aopTest() {
    Object o = (Object) applicationContext.getBean("objectAOPProxyFactoryBean");
    o.toString();
    o.equals(o);
    o.getClass();
}

给出这个输出:

SimpleMethodInterceptor: toString

似乎只有 toString() 方法被拦截了。知道为什么吗?

【问题讨论】:

    标签: java spring aop spring-aop proxyfactory


    【解决方案1】:

    奇怪。这对我来说似乎是一个错误。我无法准确解释原因,但我有一个可能的解决方法。创建一个接口并在那里重新定义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 被视为特殊情况。

    【讨论】:

    猜你喜欢
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多