Java Spring-多个方面出现故障
我在按特定顺序启动多个方面时遇到问题。我正在使用RequestProcessor对控制器上的每个传入请求执行某些操作,这些请求具有特定参数 然后我有一些特定的注释,我将只添加到控制器中的某些方法中 仅供参考,我正在使用Eclipse、Tomcat、Maven和spring以及基于java/注释的配置。我使用Tomcat和WebApplicationInitializer加载我的上下文、分派器、侦听器等。我没有web.xml。如果需要的话,我也可以发布它或pom.xml 我遇到的问题是,一个同时满足Java Spring-多个方面出现故障,java,spring,spring-mvc,aop,aspectj,Java,Spring,Spring Mvc,Aop,Aspectj,我在按特定顺序启动多个方面时遇到问题。我正在使用RequestProcessor对控制器上的每个传入请求执行某些操作,这些请求具有特定参数 然后我有一些特定的注释,我将只添加到控制器中的某些方法中 仅供参考,我正在使用Eclipse、Tomcat、Maven和spring以及基于java/注释的配置。我使用Tomcat和WebApplicationInitializer加载我的上下文、分派器、侦听器等。我没有web.xml。如果需要的话,我也可以发布它或pom.xml 我遇到的问题是,一个同时满
ProcessRequest
切入点和someAnnotation
切入点的方法首先触发someAnnotation
方法,即使指定了先触发ProcessRequest
的顺序。ProcessRequest
中设置了一些属性,这在其他一些注释中是必需的
这是我的代码的简化版本
弹簧配置类
@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();
}
}
也尝试了这种格式实现了有序的
@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
}
}
我现在还不打算将此作为答案提交,因为我想了解为什么注释或“已排序的实现”在我的项目中不能正常运行
如有任何见解,将不胜感激。谢谢
****更新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
}
}
@方面
@声明接收(“请求处理器,某些方面”)
公共类请求处理器{
@切入点(“执行(*xxx.yyy.zzz.api..*(xxx.yyy.zzz.objects.api.Request,…)&&args(Request)”
公共无效切入点(请求){}
@之前(“切入点(请求)”)
public void processRequest(请求请求)引发IOException、BadSignatureException{
//这里的一些逻辑独立于其他逻辑,需要在引用注释的其他方面之前运行
}
}
我认为问题可能是您将LTW与AspectJ一起使用,而不是将AOP与Spring一起使用,因为@Order是为Spring定义的,容器(AspectJ)无法确定这两个建议的顺序,所以请尝试以下方法之一:
@Aspect
和@order
注释的顺序@declarePresence
,然后将您的特性配置到aop.xml中
我不知道它是否会起作用,但当使用Eclipse和AspectJ支持时,它会自动在IDE中启用编译时编织,我希望能给您一个关于这一点的指针。这意味着方面被编织到您的字节码中,而Spring使用代理应用方面 使用方面声明优先级或使用
@declareReceidence
仅在使用编译时或加载时编织时有效(后者可以通过指定
来启用,具体取决于您的容器可能需要一些额外的配置)。但是,这两种方法都应该有效(您可能需要将AspectJ编译器指定为@Aspect类的编译器,而不是默认的java编译器)
@Order
和Ordered
仅适用于基于代理的解决方案,并且被AspectJ忽略 在您显示的示例中,顺序从1开始。也许没什么,但值得一试^^谢谢,我尝试了1和2,但还是没什么。即使我使用1和50,它仍然不能正常工作。总是不能正确工作。它什么时候不能工作?在与maven(从命令行)建立一场战争并将其部署到tomcat之后。或者从eclipse中运行项目?一般来说,后者使用编译时编织,这与@Order
或Ordered
没有任何关系。感谢您的评论。我没有意识到他们会有所不同。就我个人而言,我只是通过eclipse在我的本地pc上测试它,并没有尝试部署它进行测试。如果在部署之前无法测试您的实现,那将令人沮丧。是的,尝试了您建议的第一个。不记得我在哪里看到的,而且那个坏了。第二个我还没有尝试过,所以继续尝试这个@declarepreceidence(“RequestProcessor,SomeAspect”)
,但也没有成功。不知道为什么它没有拾取@Order
或@declareprecessence
注释,但它拾取的是@Aspect
注释。请划掉它。。。我刚刚注意到我的声明中有一个打字错误,于是再试了一次。现在它可以工作了,我可以删除简单的方面类来声明优先级。谢谢也作为旁白。。。我不需要声明任何aop.xml,因为我有注释,而且它仍然有效。仅供参考。。。上面是M.Deinum的评论,我验证了测试。。。@declareprecessence
与eclipse编译器一起用于本地测试,但是当通过war文件部署到tomcat时,我会得到一个堆栈跟踪,表明Spring AOP不支持@declareprecessence
。这意味着@Order
注释应该可以在部署后工作,但不能通过eclipse在本地工作。对两者都有效的唯一方法是创建一个具有声明优先级的简单方面。
@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
}
}
public aspect AspectPrecedence {
declare precedence : RequestProcessor, SomeAspect;
}
@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
}
}
<aspects>
<aspect name="your.package.RequestProcessor"/>
<aspect name="your.package.AnnotationAspect"/>
<concrete-aspect name="my_aspect_configuration_precedence"
precedence="*..*RequestProcessor, *"/>
</aspects>