我无法按特定顺序触发多个方面。我正在使用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
}
}
答案 0 :(得分:3)
使用带有AspectJ支持的Eclipse时,可以在IDE中自动启用编译时编织。这意味着方面被编织到您的字节代码中,与Spring相反,Spring使用代理来应用方面。
使用方面来声明优先级或使用@DeclarePrecedence
只能在使用编译或加载时编织时使用(后者可以通过指定<context:load-time-weaver/>
来启用,具体取决于您的容器可能需要一些额外的配置) 。但是两者都应该有效(您可能需要将AspectJ编译器指定为@Aspect类的编译器而不是默认的java编译器。)
@Order
和Ordered
仅适用于基于代理的解决方案,并且被AspectJ忽略。
答案 1 :(得分:1)
我认为问题可能是你使用带有AspectJ的LTW而不是Spring的AOP,因为@Order是为Spring定义的,容器(AspectJ)无法确定这两个建议的顺序,所以试试一个这些:
@Aspect
和@Order
注释@DeclarePrecedence
,然后将方面配置到aop.xml中<aspects> <aspect name="your.package.RequestProcessor"/> <aspect name="your.package.AnnotationAspect"/> <concrete-aspect name="my_aspect_configuration_precedence" precedence="*..*RequestProcessor, *"/> </aspects>
我不知道它是否会起作用,但希望能给你一个指针