2017-09-01 137 views
0

我正在进行的项目相当大。在试图获得加载时间编织为这个春天项目工作时,我被指示使用spring-instrument javaagent以及aspectjweaver javaagent。不过,我注意到在使用aspectjweaver代理时,我的发布时间增加了4-6倍。我还可以看到来自ContextOverridingClassLoader的4-6次相同的编织消息。为什么使用aspectjweaver javaagent进行加载时编织对我来说太慢?

但是,如果我删除了aspectjweaver,并且只使用spring-instrument,我注意到我的启动时间显着减少,每个连接点只有一个编织消息来自AppClassLoader。

唯一的问题是某些特定的类没有编织(我发现这是由于在类加载器加载错误类之前尚未加载spring应用程序上下文,因为spring是启用织)。我已经通过创建一个自定义的javaagent来找到解决方案,它可以像spring-instrument一样进行编织,只有它在premain而不是应用程序上下文加载时才这样做。它现在编织所有的课程,并在合理的时间。

但是,我不想走这条怪异的路,因为我只能假设这两个代理人的设计方式是有原因的。

我想知道是否有其他人看到与aspectjweaver javaagent类似的问题,并且如果有人可能知道为什么该代理比仅使用弹簧工具更慢。

回答

0

如果答案感兴趣的人,我已经找到了问题。

Spring使用临时类加载器ContextOverridingClassLoader在实际将它们加载到上下文之前获取有关bean类的元数据。

spring-instrument javaagent(或者更确切地说,Spring框架代码可以使用或不使用spring-instrument javaagent)专门编织由用于加载应用程序上下文的类加载器加载的类。

代码InstrumentationLoadTimeWeaver $ FilteringClassFileTransformer内:

 if (!this.targetClassLoader.equals(loader)) { 
      return null; 
     } 
     return this.targetTransformer.transform(
       loader, className, classBeingRedefined, protectionDomain, classfileBuffer); 

在另一方面,aspectjweaver没有这样一个过滤机制,因此即使将通过编织春天的临时ContextOverridingClassLoader加载的类。幸运的是,aspectjweaver有一个基本上没有记录的系统属性(或者至少我无法找到关于此的任何文档),名为aj.weaving.loadersToSkip。通过将其设置为:

-Daj.weaving.loadersToSkip=org.springframework.context.support.ContextTypeMatchClassLoader$ContextOverridingClassLoader 

我能跳过编织为类加载器和大大加快我的应用程序上下文的加载。顺便提一句,我发现spring-instrument和aspectjweaver最终都使用ClassPreProcessorAgentAdapter来编织类,因此可能不需要同时使用这两个代理(aspectjweaver将编织一个类的超集,仪器会)。但是,根据您的配置,应用程序可能会在启动时抱怨缺少的代理程序,因此您可能会将其包含在内(以一些额外的不必要开销为代价)。

相关问题