【问题标题】:Spring Boot - Can't get load time weaving with aspectj to workSpring Boot - 无法使用 aspectj 进行加载时间编织工作
【发布时间】:2014-11-01 02:33:35
【问题描述】:

谁能告诉我为什么使用spring boot时方面不会触发?我正在尝试使用 aspectj 设置加载时间编织,以便我可以建议私有方法。

这是准系统项目的链接 - https://github.com/satb/spring_aop_test_project.git

使用“-javaagent:path/to/spring-instrument-4.1.0.RELEASE.jar”(或您计算机上的其他版本的 lib)运行“App”类并运行 curl 命令

curl -i http://localhost:8080/test-app/motd

MyAspect 类有一个在调用 MyService 的私有方法时应该执行的通知。但在这种情况下,什么都不会发生。

当应用程序启动时,我看到如下消息:

[AppClassLoader@58644d46] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified.

我尝试按照这里的建议让它工作,但这没有帮助 - Using @Autowired with AspectJ and Springboot

【问题讨论】:

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


【解决方案1】:

好的,我快速浏览了您的 GitHub 项目。 POM 很奇怪,例如它不包含对 spring-instrument 的任何依赖。此外,您依赖于 aspectjweaver 1.8.2,但依赖于 aspectjrt 1.5.4。你真的应该为两者使用相同的版本。

不管怎样,我在命令行上尝试了不同的Java代理,似乎只使用AspectJ weaver(结果:异常)或仅使用Spring Instrument(结果:方面不起作用,就像你描述的那样)是不够的)。您需要同时使用两者:

java -javaagent:path/to/aspectjweaver-1.8.2.jar -javaagent:path/to/spring-instrument-4.1.0.RELEASE.jar ...

这适用于我的代码,并根据您的描述在使用 Curl 时在控制台上产生以下内容:

[AppClassLoader@58644d46] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.1.6.RELEASE)

2014-09-08 13:09:54.489  INFO 1464 --- [           main] App                                      : Starting App on Xander-PC with PID 1464 (C:\Users\Alexander\Documents\java-src\SO_AJ_SpringBootPrivilegedAspect\target\classes started by Alexander in C:\Users\Alexander\Documents\java-src\SO_AJ_SpringBootPrivilegedAspect)
2014-09-08 13:09:54.513  INFO 1464 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6771beb3: startup date [Mon Sep 08 13:09:54 CEST 2014]; root of context hierarchy
(...)
2014-09-08 13:09:56.257  INFO 1464 --- [           main] o.s.c.w.DefaultContextLoadTimeWeaver     : Found Spring's JVM agent for instrumentation
2014-09-08 13:09:56.259  INFO 1464 --- [           main] o.s.c.w.DefaultContextLoadTimeWeaver     : Found Spring's JVM agent for instrumentation
Aspect of called
(...)
2014-09-08 13:09:56.779  INFO 1464 --- [           main] App                                      : Started App in 2.531 seconds (JVM running for 3.067)
2014-09-08 13:09:59.115  INFO 1464 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2014-09-08 13:09:59.115  INFO 1464 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2014-09-08 13:09:59.122  INFO 1464 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 7 ms
Aspect of called
Advising getter

【讨论】:

  • @kregaex - 谢谢。看起来我错过了将 aspectjweaver 添加为 javaagent。没有意识到它是必需的。尽管当其他人遇到同样的问题时,我在 SO 上读到了它,但当我在之前的测试中添加它时,它对我不起作用。因此,我认为这不是问题,所以将其删除。但也许当时的问题是别的东西。再次为同样的问题感到抱歉。我应该将这个准系统项目链接添加到另一个问题本身。
  • 一个更简单的解决方案是动态加载代理而不需要 jvm 参数:github.com/subes/invesdwin-instrument
  • 我想了解的是,为什么我需要同时加载两个 Java 代理?文档没有提到
  • 我不是 Spring 用户,我只是想提供帮助。我是 AspectJ 专家,因此我还可以通过 Spring 中的 LTW 对 Spring AOP 或 AspectJ 提供一些帮助。 documentation 实际上说任何一个代理都应该足够了。也许有一种方法可以使用spring-instrument,如果操作正确,它会自动加载AspectJ weaver。但是“做得对”到底是什么意思,我不知道。还有其他人比我更有资格回答这个问题。但它确实适用于命令行上的两个代理。
【解决方案2】:

尝试声明 InstrumentationLoadTimeWeaver bean,而不是显式使用 -javaagent:/path/to/org.springframework.instrument-{version}.jar。根据文档

要使用它,您必须通过提供以下 JVM 选项来使用 Spring 代理启动虚拟机:

-javaagent:/path/to/org.springframework.instrument-{version}.jar

请注意,这需要修改 VM 启动脚本,这可能会阻止您在应用服务器环境中使用它(取决于您的操作策略)。此外,JDK 代理将检测整个 VM,这可能会很昂贵。

我希望按照下面的方式做会更好。

@Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver()  throws Throwable {
    InstrumentationLoadTimeWeaver loadTimeWeaver = new InstrumentationLoadTimeWeaver();
    return loadTimeWeaver;
}

xml 配置中也可以这样做。

找到了一个新的library,它只是解决了动态设置 spring InstrumentationLoadTimeWeaver 以启用对方面的支持,而无需使用显式 java 代理启动 JVM

<dependency>
    <groupId>de.invesdwin</groupId>
    <artifactId>invesdwin-instrument</artifactId>
    <version>1.0.2</version>
</dependency>

春季启动配置

@SpringBootApplication
/** 
 * Make @Configurable work via @EnableLoadTimeWeaving.
 * If it does not work, alternatively you can try: 
 * @ImportResource(locations = "classpath:/META-INF/ctx.spring.weaving.xml") 
 */
@EnableLoadTimeWeaving
public class MySpringBootApplication {
    public static void main(final String[] args) {
        DynamicInstrumentationLoader.waitForInitialized(); //dynamically attach java agent to jvm if not already present
        DynamicInstrumentationLoader.initLoadTimeWeavingContext(); //weave all classes before they are loaded as beans
        SpringApplication.run(MySpringBootApplication.class, args); //start application, load some classes
    }
}

【讨论】:

  • 这不适用于 spring boot jar github.com/spring-projects/spring-boot/issues/739
  • 我使用 spring boot jar 实现了它并让它在生产应用程序中工作,实现与 spring boot 或普通 spring 实现应该没有任何不同。
  • 您是否使用嵌入式 tomcat 服务器部署了您的 Spring Boot 应用程序?
  • 是的,应用程序在嵌入式 tomcat 服务器中运行。
  • 那我想知道this bug是什么意思?
猜你喜欢
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多