简体   繁体   English

EnableLoadTimeWeaving Spring Boot嵌入式Tomcat

[英]EnableLoadTimeWeaving Spring Boot Embedded Tomcat

Caching Aspects are not having any effects at runtime with Spring Boot and Embedded tomcat with LoadTimeWeaving enabled,but we are seeing the weaving is happening fine in the logs. 缓存方面在启用SpringTime和启用了LoadTimeWeaving的嵌入式tomcat的情况下,在运行时不会产生任何影响,但是我们看到在日志中进行编织的情况很好。

Below is the configuration, the LoadTimeWeaving is enabled along with the mode as AspectJ for Caching 下面是配置,启用了LoadTimeWeaving以及作为AspectJ进行缓存的模式

    @Configuration
    @EnableConfigurationProperties
    @EnableSpringConfigured
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @EnableLoadTimeWeaving
    @EnableTransactionManagement
    @EnableAsync
    @EnableCaching(mode = AdviceMode.ASPECTJ)
    public class AppConfig {
    }

Spring Agent -javaagent:../../../spring-instrument-4.3.3.RELEASE.jar Spring Agent -javaagent:../../../ spring-instrument-4.3.3.RELEASE.jar

Logs 日志

[RestartClassLoader@2aaae670] debug weaving 'uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway'
[RestartClassLoader@2aaae670] weaveinfo Join point 'method-execution(java.util.List uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway.getHierarchyLevelDefns())' in Type 'uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway' (RestReferenceDataGateway.java:118) advised by around advice from 'org.springframework.cache.aspectj.AnnotationCacheAspect' (AbstractCacheAspect.aj:64)
[RestartClassLoader@2aaae670] weaveinfo Join point 'method-execution(java.util.Map uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway.getHierarchyLevelDefinitionMap())' in Type 'uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway' (RestReferenceDataGateway.java:129) advised by around advice from '**org.springframework.cache.aspectj.AnnotationCacheAspect**' (AbstractCacheAspect.aj:64)
[RestartClassLoader@2aaae670] **debug generating class** 'uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway$AjcClosure1'
[RestartClassLoader@2aaae670] debug generating class 'uk.co.loyalty.iss.newpro.reporting.domain.refdata.gateway.RestReferenceDataGateway$AjcClosure3'

there are whole bunch of discussions around this. 关于这一点,有很多讨论。 The weaving is happening on the RestartClassLoader, not sure is it something to do with the class loader. 编织发生在RestartClassLoader上,不确定是否与类加载器有关。 Have also tried adding the below, 还尝试添加以下内容,

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

Please provide your suggestions. 请提供您的建议。

Edit We need Aspectj mode as we are using caching on private methods. 编辑我们需要使用Aspectj模式,因为我们在私有方法上使用缓存。 I removed the EnableAspectJAutoProxy but still that does not help. 我删除了EnableAspectJAutoProxy,但这仍然无济于事。

On further analysis on the load time weaving, I noticed the below behaviour. 在对加载时间编织进行进一步分析时,我注意到了以下行为。 I profile the application and investigated on the class loaders to see the weaving is done correct for the caching annotation to work(classes are trasformed). 我对应用程序进行了概要分析,并在类加载器上进行了研究,以确保编织正确完成,以便缓存批注可以正常工作(类已转换)。 I noticed for some classes in the classloader ,we have a class with suffix($AjcClosure and those are transformed classes after weaving is done). 我注意到对于类加载器中的某些类,我们有一个带后缀的类($ AjcClosure,在编织完成后将它们转换为类)。 So, if cachinng annotations is part of those weaved classes, then it works fine. 因此,如果cachinng注释是这些编织类的一部分,则它可以正常工作。 Then I closely looked in to the classes why some classes are weaved correctly and some are not. 然后,我仔细查看了这些类,为什么有些类不能正确编织,而有些则不能。 Then I noticed that if classes are loaded already to the class-loader before weaving happens, then that is where the weaving is not happening. 然后我注意到,如果在编织发生之前就已经将类加载到了类加载器中,那么编织就不会发生。

   @Bean
    public IAService aService(){
       return new AServiceImpl();
    }

In the above case, the class is AServiceImpl is loaded to the class loader only when this instance is needed (after load time weaving and caching works perfectly). 在上述情况下,仅在需要此实例时(加载时进行编织和缓存的工作原理完美之后),将类AServiceImpl加载到类加载器。 But if the same class is being initialised using @Component then it is not getting weaved. 但是,如果使用@Component初始化相同的类,则不会被编织。

@Service
public class AServiceImpl{
}

I think, in the above case, the class AServiceImpl is loaded to the class loader while the spring container initialises and load time weaving is trying to weave after that). 我认为,在上述情况下,将类AServiceImpl加载到类加载器中,同时弹簧容器初始化,并在此之后尝试织入加载时间。

I verified this behavior again in class loader as well. 我也在类加载器中再次验证了此行为。 So, is it an issue if aspectj tries to weave a class that was already loaded. 因此,如果aspectj尝试编织一个已经加载的类,这是一个问题吗? the same problem was raised in the Spring Jira as well in the below link. 以下链接在Spring Jira中也提出了相同的问题。

https://jira.spring.io/browse/SPR-13786 https://jira.spring.io/browse/SPR-13786

As mentioned in the above link, if I pass the aspectj weaver as java agent like the below, then all the classes are being weaved correctly. 如上面的链接所述,如果我像下面那样将aspectj weaver作为java代理传递,那么所有类都将被正确编织。 So, is it required to have two agents or do we have any other option for this. 因此,是需要两个代理还是我们有其他选择。

-javaagent:../../../aspectjweaver-1.6.1.jar 
-javaagent:../../../spring-instrument-4.3.3.RELEASE.jar 

Yes, the weaver needs to be active before the weaving targets are loaded by the classloader. 是的,在类加载器加载编织目标之前 ,编织器需要处于活动状态。

Now, I am an AspectJ geek but not a container geek, I mainly work with Java SE and no containers. 现在,我是一个AspectJ怪胎,但不是容器怪胎,我主要使用Java SE而不使用容器。 Please try to also add 请尝试同时添加

-javaagent:path/to/aspectjweaver.jar

to your command line and see if it helps. 到命令行,看看是否有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM