【问题标题】:Spring AOP (Aspect) Not executingSpring AOP(方面)未执行
【发布时间】:2013-01-05 20:06:05
【问题描述】:

我正在使用 Spring 2.5.6、asm 1.5.3、aspectjrt/aspectjweaver 1.6.1、cglib 2.1_3 在我基于 Web 的 Spring 应用程序中,我有以下类:

package uk.co.txttools.aspects;

@Aspect
public class LoggingAspect {
    @Before("execution(* uk.co.txttools.web.controller.compose.PreviewMessageController.set*(..))")
    public void setLoggingAdvice(){
        System.out.println("********************************* Advice run..... set mothod called....");
    }

    @AfterThrowing("execution(* uk.co.txttools.web.controller.compose.PreviewMessageController.onSubmit(..) throws java.lang.Exception)")
    public void hadleException(){
       System.out.println("================= PreviewMessageController =========== ON SUBMIT Exception Throwen ==================");
    }

    @Before("execution(* uk.co.txttools.web.controller.compose.PreviewMessageController.onSubmit(..) throws java.lang.Exception)")
    public void OnSubmitAspect(){
        System.out.println("================= PreviewMessageController =========== ON SUBMIT CALLED ==================");
    }
}

我有一个Controller:uk.co.txttools.web.controller.compose.PreviewMessageController which hasonSubmit()method, which get called from web page. I have separateapplicationContext.xml`文件。

我的springapp-servlet.xml(在带有 org.springframework.web.servlet.DispatcherServlet 的 web.xml 文件中使用)文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">

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

<bean id="loggingAspect" class="uk.co.txttools.aspects.LoggingAspect" />
.
.

在同一个xml文件PreviewMessageController下面得到初始化,这意味着我的Controller和Aspect live是同一个容器。

我在运行应用程序时没有遇到任何异常,但我的方面类 LoggingAspect 从未被调用。 我不确定缺少什么或我做错了。 请帮帮我..

谢谢

【问题讨论】:

    标签: spring spring-mvc aop spring-aop


    【解决方案1】:

    我不确定我是否做得正确,但对我来说解决的方法是将 @Component 添加到“Aspect'ed”类 -

    @Aspect
    @Component
    public class PerformanceLogger {
    
        private Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Around("within(com.something.rest.service..*)")
        public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
            long start = System.currentTimeMillis();
            Object retVal = pjp.proceed();
            long end = System.currentTimeMillis();
            logger.debug(pjp.getSignature().toShortString() + " Finish: " + (end - start) + "ms");
            return retVal;
        }
    }
    

    (并且只是为了结束循环 - 如果您使用基于注释,请不要忘记将 @EnableAspectJAutoProxy 添加到您的 Config 类。

    @EnableAspectJAutoProxy
    

    【讨论】:

    • 我想知道为什么这在文档中没有更清楚。它也解决了我的问题。
    • @idipous 我相信清除这一点的文档是link您可以在 Spring XML 配置中将方面类注册为常规 bean,或者通过类路径扫描自动检测它们 - 就像任何其他 Spring 管理的 bean。但是,请注意@Aspect 注解不足以在类路径中进行自动检测:为此,您需要添加单独的@Component 注解...
    • @Arpit 简而言之,@Aspect 不是 Spring 注解,而是 AspectJ 注解。这就是为什么您需要通过添加 Spring 特定的注释来将您创建的方面标记为 Spring 组件。
    • @Inject 也不是 Spring 特定的注释,但 spring 可以识别它。一旦你加载了 spring-aop 或 spring-aspects 库,他们可能(如果你问我真的应该)已经付出了额外的努力,让 (@)Aspect Behave 作为 (@)Compenent ...
    【解决方案2】:

    对于那些选择JavaConfig 的人,您可以将您的Aspect 声明为一个bean 并添加@EnableAspectJAutoProxy 注释以打开自动代理:

    @Configuration
    @EnableAspectJAutoProxy
    @ComponentScan
    public class MyConfig {
        @Bean
        public LoggingAspect loggingAspect(){
            return new LoggingAspect();
        }
    }
    

    【讨论】:

      【解决方案3】:

      终于解决了。

      我想我错过了 aspectj-maven-plugin。它需要春天来编织方面。但是,没有教程提供此信息。在我的 pom.xml 中添加了以下内容。

      <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>aspectj-maven-plugin</artifactId>
          <version>1.0</version>
          <dependencies>
              <dependency>
                  <groupId>org.aspectj</groupId>
                  <artifactId>aspectjrt</artifactId>
                  <version>1.6.1</version>
              </dependency>
              <dependency>
                  <groupId>org.aspectj</groupId>
                  <artifactId>aspectjtools</artifactId>
                  <version>1.6.1</version>
              </dependency>
          </dependencies>
          <executions>
              <execution>
                  <goals>
                      <goal>compile</goal>
                      <goal>test-compile</goal>
                  </goals>
              </execution>
          </executions>
          <configuration>
              <outxml>true</outxml>
              <verbose>true</verbose>
              <showWeaveInfo>true</showWeaveInfo>
              <aspectLibraries>
                  <aspectLibrary>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-aspects</artifactId>
                  </aspectLibrary>
              </aspectLibraries>
              <source>1.6</source>
              <target>1.6</target>
          </configuration>
      </plugin>
      

      谢谢大家

      【讨论】:

      • 不,编织 Spring AOP 方面不需要该插件,仅当您想使用完整的 AspectJ 加载时编织或编译时编织时。你所做的是使用 CTW。真正的解决办法是修复您的 Spring AOP 配置。
      【解决方案4】:

      如果你还没有尝试过...尝试基于xml的spring-aop配置如下:

          <aop:config>
          <aop:aspect ref="loggingAspect">
              <aop:pointcut expression="execution(* uk.co.txttools.web.controller.compose.PreviewMessageController.set*(..))" id="previewMessageControllerSetters"/>
              <aop:before method="setLoggingAdvice" pointcut-ref="previewMessageControllerSetters"/>
      
               // set other 2 pointcuts similarly....
              </aop:aspect>       
          </aop:config>
          <bean id="loggingAspect" class="uk.co.txttools.aspects.LoggingAspect" />
      

      【讨论】:

      • 感谢 Vikram 的回复,但我也试过了,即使基于 XML 的配置也不起作用。我认为 Cglib 无法为我生成代理。有什么建议吗????
      • @bhavin.patel 我认为您对proxy-target-class="true" 所做的事情应该可以达到您的目的...我认为问题可能出在 aspectjrt 和 aspectjweaver jar 文件上...我使用 Spring 3.0 aspectjrt 和 aspectweaver 版本 1.6.8。如果您的项目是基于 Maven 的,并且如果您不介意升级到 Spring 3.0,您可以快速交换并检查..
      • 如果你可以在你的代码中换掉 cglib 依赖并检查它是否适用于 Spring 2.5/AspectJ 1.5.3,那就更好了。如果您使用的是 Spring IDE,那么您将在所有建议的方法上都有标记...这样至少您可以了解您的方面是否正在编译...
      【解决方案5】:

      只是为了使可能的答案列表完整:

      在我看来,您的 maven pom.xml 中缺少以下依赖项:

      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>2.5.6</version>
      </dependency>
      

      【讨论】:

        【解决方案6】:

        在你的配置文件中试试这个:

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

        【讨论】:

        • 它仍然不起作用,我仍然没有例外,但我的方面从未被调用。我认为我的控制器没有被代理,因此 AOP 不起作用。我认为在路径中有 cglib 并有 可以解决这个问题,但不确定缺少什么?
        猜你喜欢
        • 2011-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多