我與下面的Spring(4.0.6.RELEASE)結構的現有WAR:AspectJ的建議
<beans>
<context:annotation-config/>
<context:component-scan base-package="org.example"/>
</beans>
向該應用添加以下注釋界面(逐字拷貝):
package org.example;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface Logged {}
以下方面類(複製逐字爲好):
package org.example;
@Aspect
@Component
public class LoggingAspect
{
@Before("@annotation(Logged)")
public void before()
{
System.out.println("LoggingAspect.before()");
}
}
和下面的批量處理類(逐字拷貝):
package org.example;
@Component
public class Batch
{
@Logged
@Scheduled(fixedDelay = 100)
public void execute()
{
System.out.println("Batch.execute()");
}
}
Spring配置,然後變更爲:
<beans>
<aop:aspectj-autoproxy proxy-target-class="true"/>
<context:annotation-config/>
<context:component-scan base-package="org.example"/>
<task:annotation-driven executor="executor" scheduler="scheduler"/>
<task:executor id="executor" pool-size="5"/>
<task:scheduler id="scheduler" pool-size="5"/>
</beans>
我期待在控制檯上看到下面的消息:
LoggingAspect.before()
Batch.execute()
但是,我只看到這些消息中的第二個(即沒有調用方面代碼)。
我把這段代碼拿到了一個示例應用程序中,有趣的是這兩條消息在示例應用程序中顯示得很好。然後,我將實際應用程序中的每個文件與樣本進行比較,並確保所有內容完全相同,包括類和文件名。然而,這個方面在實際應用中並不起作用。
在這兩個應用程序打開的調試級別的日誌,示例應用程序顯示以下日誌消息:
DEBUG org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory - Found AspectJ method: public void org.example.LoggingAspect.before()
但實際應用中沒有這個日誌消息。這似乎表明示例應用程序檢測到方面方法,但實際的應用程序沒有。兩者都使用相同的Spring和AspectJ版本(分別爲4.0.6.RELEASE和1.8.1)。兩個日誌都沒有錯誤。
在這兩種情況下(從日誌中搜集到),彈簧都會實例化LoggingAspect
。
我也檢查了兩個應用程序的各種JAR依賴關係,除了實際的應用程序使用示例應用程序沒有的Spring ORM,Hibernate和EHCACHE JAR之外,其它都一樣。
任何應該檢查的指針都是有用的。