在Spring应用程序中未检测到AspectJ建议

时间:2014-07-19 07:51:46

标签: spring-aop

我有一个带有以下Spring(4.0.6.RELEASE)配置的现有WAR:

<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 {}

以下Aspect类(也是逐字复制的):

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)。两个日志都没有错误。

Spring在两种情况下实例化LoggingAspect(从日志中收集)。

我还检查了两个应用程序的各种JAR依赖关系,一切都是一样的,除了实际的应用程序使用的是示例应用程序没有的Spring ORM,Hibernate和EHCACHE JAR。

任何关于应该检查其他内容的指针都很有用。

1 个答案:

答案 0 :(得分:0)

尽管调试应用程序数月,升级和降级各种Spring和AspectJ版本,但问题无法解决。有趣的是,从受影响的类创建的示例应用程序没有显示任何问题。

我必须通过在Spring配置中指定方面来解决问题。这一行:

<aop:aspectj-autoproxy proxy-target-class="true"/>

必须改为:

<aop:aspectj-autoproxy proxy-target-class="true">
  <aop:include name="loggingAspect"/>
</aop:aspectj-autoproxy>

在这种情况下,loggingAspect是Spring框架为bean类LoggingAspect的实例分配的默认bean名称。如果bean名称设置为其他值,则该值必须与<aop:include />一起使用。