2012-06-07 34 views
0

我玩弄編程實現的Spring AOP。 我創建了生產AOP Object.class代理 與MethodInterceptors給定的列表中選擇一個簡單的工廠類:實施方案的Spring AOP與ProxyFactory通過

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以下(建議ADVI ce):'...請注意,給定的建議將適用於所有代理上的調用,甚至toString()方法!...'

所以,我期待所有的呼叫由SimpleMethodInterceptor攔截的Object.class方法。

測試:

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

給出了這樣的輸出:

SimpleMethodInterceptor:的toString

似乎只有toString()方法得到了攔截。任何想法爲什麼?

回答

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被視爲一種特殊情況。

+0

應該使用CGLIB無界面運行,檢查:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop-api.html#aop-pfb-proxy-types –