Spring - 多个方面失败

时间:2013-10-31 16:15:57

标签: java spring spring-mvc aop aspectj

我无法按特定顺序触发多个方面。我正在使用RequestProcessor对我的控制器上的每个传入请求执行某些操作,这些请求具有某个参数

然后我有一些特定的注释,我将只添加到我的控制器中的某些方法。

仅供参考我使用Eclipse,Tomcat,Maven和spring使用基于java / annotation的配置。我使用Tomcat和WebApplicationInitializer来加载我的上下文,调度程序,监听器等。我没有web.xml。如果需要,我也可以发布那个或pom.xml。

我得到的问题是,满足ProcessRequest切入点和someAnnotation切入点的方法首先触发someAnnotation方法,即使指定了命令来激活ProcessRequest 1}}首先。在ProcessRequest中设置了一些在其他注释中需要的属性。

以下是我的代码的简化版本。

Spring Config Class

@Configuration  // Enable Spring Annotation Configuration. Equivalent to <context:annotation-config/>
@EnableAspectJAutoProxy
@EnableCaching  // Enable Spring caching
@EnableWebMvc   // Enable Spring MVC Annotation. Equivalent to <mvc:annotation-driven />.
@ComponentScan(basePackages = {"xxx.yyy.zzz"}) // Scan for Spring Components.      Equivalent to <context:component-scan>
public class WebAppConfig extends WebMvcConfigurerAdapter {

    // Other Bean logic here

    @Bean
    public RequestProcessor requestProcessor() {
        return new RequestProcessor();
    }

    @Bean
    public AnnotationAspect annotationAspect() {
        return new AnnotationAspect();
    }
}

方面#1

@Aspect
@Order(0)
public class RequestProcessor {

    @Pointcut("execution(* xxx.yyy.zzz.api..*.*(xxx.yyy.zzz.objects.api.Request,..)) && args(request)")
    public void pointcut(Request<?> request) {}

    @Before("pointcut(request)")
    public void processRequest(Request<?> request) throws IOException, BadSignatureException {
        // Some logic here that is independent of other and needs to run before other aspect which references annotation
    }
}

方面#2

@Aspect
@Order(1)
public class AnnotationAspect {

    @Before("@annotation(xxx.yyy.zzz.annotation.SomeAnnotation)")
    public void someAnnotation() {
        // Log for this annotation
    }

    // Some other annotation methods here
}

也尝试了这种格式implements Ordered

@Aspect
public class RequestProcessor implements Ordered {

    @Override
    public int getOrder() {
        return 0;
    }

    @Pointcut("execution(* xxx.yyy.zzz.api..*.*(xxx.yyy.zzz.objects.api.Request,..)) && args(request)")
    public void pointcut(Request<?> request) {}

    @Before("pointcut(request)")
    public void processRequest(Request<?> request) throws IOException, BadSignatureException {
        // Some logic here that is independent of other and needs to run before other aspect which references annotation
    }
}

我读过这篇文章和其他一些文章,但找不到任何相关的文章。

Ordering aspects with Spring AOP && MVC

**** **** UPDATE

所以我一直在阅读有关宣布优先权的AspectJ文档,所以我想我会给它一个旋转。我创建了一个简单的方面,只声明优先级,它工作正常。

这是我的优先级方面:

public aspect AspectPrecedence {
    declare precedence : RequestProcessor, SomeAspect;
}

我不打算将此作为答案提交,因为我想理解为什么注释或“实现Ordered”在我的项目中无法正常运行。

非常感谢任何见解。谢谢!

****更新2 ****

作为参考,这在我的eclipse环境中本地工作,并且当通过WAR文件部署到AWS时似乎有效。

@Aspect
@DeclarePrecedence("RequestProcessor, SomeAspect")
public class RequestProcessor {

    @Pointcut("execution(* xxx.yyy.zzz.api..*.*(xxx.yyy.zzz.objects.api.Request,..)) && args(request)")
    public void pointcut(Request<?> request) {}

    @Before("pointcut(request)")
    public void processRequest(Request<?> request) throws IOException, BadSignatureException {
        // Some logic here that is independent of other and needs to run before other aspect which references annotation
    }
}

2 个答案:

答案 0 :(得分:3)

使用带有AspectJ支持的Eclipse时,可以在IDE中自动启用编译时编织。这意味着方面被编织到您的字节代码中,与Spring相反,Spring使用代理来应用方面。

使用方面来声明优先级或使用@DeclarePrecedence只能在使用编译或加载时编织时使用(后者可以通过指定<context:load-time-weaver/>来启用,具体取决于您的容器可能需要一些额外的配置) 。但是两者都应该有效(您可能需要将AspectJ编译器指定为@Aspect类的编译器而不是默认的java编译器。)

@OrderOrdered仅适用于基于代理的解决方案,并且被AspectJ忽略。

答案 1 :(得分:1)

我认为问题可能是你使用带有AspectJ的LTW而不是Spring的AOP,因为@Order是为Spring定义的,容器(AspectJ)无法确定这两个建议的顺序,所以试试一个这些:

  1. 尝试翻转@Aspect@Order注释
  2. 的顺序
  3. 您可以尝试AspectJ中的注释@DeclarePrecedence,然后将方面配置到aop.xml中
  4. <aspects>        
            <aspect name="your.package.RequestProcessor"/>
            <aspect name="your.package.AnnotationAspect"/>
               <concrete-aspect name="my_aspect_configuration_precedence"
                    precedence="*..*RequestProcessor, *"/>
    </aspects>
    

    我不知道它是否会起作用,但希望能给你一个指针