【问题标题】:How to use Spring AOP + AspectJ LTW combined in one application?如何在一个应用程序中结合使用 Spring AOP + AspectJ LTW?
【发布时间】:2019-09-12 04:18:16
【问题描述】:

也许这里有些人认识我。通常我是回答 AspectJ 问题的人。我认为自己是那里的专家。在许多情况下,即使我不是 Spring 用户,我也会回答 Spring AOP 问题。

不过,有两件事对我来说一直很神秘:

  1. SO 和网络上其他地方的许多来源声称,将 Spring AOP 与 AspectJ 结合起来很容易,更准确地说是与加载时编织 (LTW) 结合。 只要 AspectJ通过编译时编织 (CTW) 应用我没有异议,因为在 Spring 应用程序启动之前已经应用了一个 (AspectJ),因此在这种情况下没有问题。但是,当我尝试将 Spring 配置为使用 Spring AOP 并同时在 Java 命令行上使用 -javaagent:/path/to/aspectjweaver.jar 启动应用程序时,我只能让加载时编织 (LTW) 工作,而不再是 Spring AOP,没有不管@EnableAspectJAutoProxy@EnableLoadTimeWeaving 的组合我试过。

  2. 作为一个侧面展示,我还想知道为什么 AspectJ LTW 从来没有像 Spring 手册所宣传的那样只使用 -javaagent:/path/to/spring-instrument.jar 甚至不应用任何代理。手册说 Spring 可以检测到 aop.xml,然后在运行中自动激活 LTW。这对我永远不起作用。准确地说,使用 spring-instrument 代理 Spring 确实检测到我的方面并注册它们,但只有在 AspectJ 编织并直接在我的应用程序的主类中使用的目标类类已经加载之后。 IE。 AspectJ 编织器初始化太晚。

谁能在这里启发我并告诉我如何正确设置?这个问题与my answer here有关,因此您可以方便地克隆那里提到的示例GitHub project,切换到aspectj-ltw分支并从那里获取以配置应用程序以便仅通过AspectJ使用TaskAspects LTW(因为它拦截了其他方面,这在 Spring AOP 中是不可能的)和其他方面通过 Spring AOP。我真的很想看看这是否以及如何结合。

【问题讨论】:

  • 我从来没有自己做过,但是我知道有@EnableLoadTimeWeaving注解可以用于这个目的。在这里找到了示例。 concretepage.com/spring/enableloadtimeweaving-spring-example。希望它以某种方式有所帮助:)
  • 在回答之前先阅读我的问题和链接资源会很好。我知道如何激活 LTW,我什至在这个问题中提到了@EnableLoadTimeWeaving。问题是关于如何将 Spring AOP 方面与 AspectJ 方面组合,即同时使用两者。 Spring 手册声称这是可能的,但没有全面解释如何。
  • 我什至不知道 spring 可以选择像这样自动启用 LTW。我一直手动使用代理定义。但老实说,一旦我决定将完整的 AJ 添加到 Spring 项目中,我并没有发现使用 SpringAOP 的有限支持并完全坚持使用 AJ 的价值。
  • 我只是好奇,仅此而已。文档和其他来源说你可以结合它,所以我想知道如何。如果您无论如何都在那个环境中工作并且只是在需要的地方添加额外的东西,那么将 Spring 的基础设施与组件配置、依赖注入等一起使用实际上是有意义的。我开始怀疑没有人真正知道如何做到这一点,或者在过去几年中尝试过,这可以解释没有示例的原因。但我还没有放弃。
  • 我真的很想知道反对票是为了什么。这个问题有什么问题或不好的地方?

标签: spring spring-boot aspectj spring-aop load-time-weaving


【解决方案1】:

问题似乎是Spring Boot的配置扫描过程,而不是Spring Framework本身。 它评估来自各种自动配置类的条件并最终加载JobProcessImpl,因为在启用LoadTimeWeaver 之前使用@Component 进行注释。

我发现使它工作的方法是从类中删除@Component 注释并在ApplicationConfig 中手动创建bean:

@Bean
public JobProcess jobProcess() {
    return new JobProcessImpl();
}

2019-09-20 12:10:26.985  INFO 1 --- [           main] AspectJ Weaver                           : [AspectJ] register aspect com.spring.aspect.dynamicflow.aspect.TaskAspects
2019-09-20 12:10:27.155  INFO 1 --- [           main] AspectJ Weaver                           : [AspectJ] register aspect com.spring.aspect.dynamicflow.activity.AnnotationTask
2019-09-20 12:10:27.166  INFO 1 --- [           main] AspectJ Weaver                           : [AspectJ] register aspect com.spring.aspect.dynamicflow.activity.ReviewTask
2019-09-20 12:10:27.257  INFO 1 --- [           main] AspectJ Weaver                           : [AspectJ] Join point 'method-execution(java.lang.Object com.spring.aspect.dynamicflow.process.JobProcessImpl.process(com.spring.aspect.dynamicflow.entity.JobContext))' in Type 'com.spring.aspect.dynamicflow.process.JobProcessImpl' (JobProcessImpl.java:16) advised by around advice from 'com.spring.aspect.dynamicflow.activity.ReviewTask' (Task.java)
2019-09-20 12:10:27.263  INFO 1 --- [           main] AspectJ Weaver                           : [AspectJ] Join point 'method-execution(java.lang.Object com.spring.aspect.dynamicflow.process.JobProcessImpl.process(com.spring.aspect.dynamicflow.entity.JobContext))' in Type 'com.spring.aspect.dynamicflow.process.JobProcessImpl' (JobProcessImpl.java:16) advised by around advice from 'com.spring.aspect.dynamicflow.activity.AnnotationTask' (Task.java)
2019-09-20 12:10:27.378  INFO 1 --- [           main] AspectJ Weaver                           : [AspectJ] Join point 'method-execution(java.lang.Object com.spring.aspect.dynamicflow.activity.AnnotationTask.task(org.aspectj.lang.ProceedingJoinPoint, com.spring.aspect.dynamicflow.entity.JobContext))' in Type 'com.spring.aspect.dynamicflow.activity.AnnotationTask' (AnnotationTask.java:16) advised by around advice from 'com.spring.aspect.dynamicflow.aspect.TaskAspects' (TaskAspects.java)
2019-09-20 12:10:27.390  INFO 1 --- [           main] AspectJ Weaver                           : [AspectJ] Join point 'method-execution(java.lang.Object com.spring.aspect.dynamicflow.activity.ReviewTask.task(org.aspectj.lang.ProceedingJoinPoint, com.spring.aspect.dynamicflow.entity.JobContext))' in Type 'com.spring.aspect.dynamicflow.activity.ReviewTask' (ReviewTask.java:16) advised by around advice from 'com.spring.aspect.dynamicflow.aspect.TaskAspects' (TaskAspects.java)
2019-09-20 12:10:27.412  INFO 1 --- [           main] c.s.a.d.process.JobProcessImpl           : JobProcessImpl class was loaded
2019-09-20 12:10:27.500  WARN 1 --- [           main] AspectJ Weaver                           : [AspectJ] javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
2019-09-20 12:10:27.871  INFO 1 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-09-20 12:10:28.368  INFO 1 --- [           main] c.spring.aspect.dynamicflow.Application  : jobProcess = com.spring.aspect.dynamicflow.process.JobProcessImpl@4627a09d
2019-09-20 12:10:28.379  INFO 1 --- [           main] c.s.a.dynamicflow.aspect.TaskAspects     : Handling the task aspects.
2019-09-20 12:10:28.382  INFO 1 --- [           main] c.s.a.dynamicflow.aspect.TaskAspects     :   execution(Object com.spring.aspect.dynamicflow.activity.AnnotationTask.task(ProceedingJoinPoint, JobContext))
2019-09-20 12:10:28.382  INFO 1 --- [           main] c.s.a.d.activity.AnnotationTask          : AnnotationTask's task
2019-09-20 12:10:28.382  INFO 1 --- [           main] c.s.a.d.activity.AnnotationTask          :   Setting that the annotation is done.
2019-09-20 12:10:28.395  INFO 1 --- [           main] c.s.a.dynamicflow.aspect.TaskAspects     : Handling the task aspects.
2019-09-20 12:10:28.395  INFO 1 --- [           main] c.s.a.dynamicflow.aspect.TaskAspects     :   execution(Object com.spring.aspect.dynamicflow.activity.ReviewTask.task(ProceedingJoinPoint, JobContext))
2019-09-20 12:10:28.395  INFO 1 --- [           main] c.s.a.dynamicflow.activity.ReviewTask    : ReviewTask's task
2019-09-20 12:10:28.395  INFO 1 --- [           main] c.s.a.dynamicflow.activity.ReviewTask    :   Setting that the review is done.
2019-09-20 12:10:28.395  INFO 1 --- [           main] c.s.a.d.process.JobProcessImpl           : Processing the job with jobid 11

【讨论】:

  • 根据我对 Spring 处理注释和 bean 发现的记忆,这很有意义。但是,我也认为这是 Spring Boot 中的一个重大错误;在这种情况下,对于依赖于注释扫描的绝大多数代码/库,它基本上禁用了 AJ 的 LTW。我想知道是否有人在 Boot 项目上打开了一个 bug 来表明这一点
  • 这对我不起作用。您究竟是如何配置 Spring(通过ApplicationConfig 类)、AspectJ(通过 aop.xml)以及如何运行应用程序(-javaagent 参数)以便混合 Spring AOP 和 AspectJ?请记住,只有TaskAspects 旨在通过 AspectJ 运行,其他方面通过 Spring AOP 运行。对我来说,一旦 Spring Boot 检测到 AspectJ,基于代理的 Spring AOP 就会完全停用。
  • 我可以确认您的解决方法解决了问题 2(侧面展示),即 AspectJ LTW 适用于所有 3 个方面,只有 -javaagent:/my/path/spring-instrument.jar@EnableLoadTimeWeaving(aspectjWeaving = ENABLED) 结合使用(注释参数是强制性的或否则它将不起作用)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多