使用编译时编织实现Spring @Configurable的启动性能

时间:2009-07-16 09:57:24

标签: spring performance spring-aop configurable compile-time-weaving

这是我关于堆栈溢出的第一个问题,所以请善待。

我正在使用

运行应用
  • spring 2.5.x
  • 可配置注释
  • 编制时间编织(CTW)
  • 行家
  • 蚀/ AJDT

我使用CTW,一切运行正常。但是如果我第一次实例化一个带注释的类需要很长时间。第二次非常快。

查看第一次调用的探查器堆栈跟踪,我看到93%的时间被使用 org.aspectj.weaver.internal.tools.PointcutExpressionImpl.matchesMethodExecution(方法)

在第二次调用的堆栈跟踪中,此方法仅使用1%的时间。更糟糕的是:第一次通话的时间大约是第二次通话的10倍。

我想知道,因为我认为CTW不再需要织布工。

但是,只要有人在这个类上调用new,它就会开始分析原型bean。它使用aspectj weaver来分析需要完成的工作,并为下一次调用加快此过程做好准备。

有没有人有加快初始化注释类的第一次调用的经验?

这是我的pom的片段:

 <plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>aspectj-maven-plugin</artifactId>
 <executions>
    <execution>
      <goals>
        <goal>test-compile</goal>
        <goal>compile</goal>
      </goals>
</execution>
 </executions>
 <dependencies>
   <dependency>
     <groupId>org.aspectj</groupId>
     <artifactId>aspectjtools</artifactId>
     <version>1.6.1</version>
   </dependency>
 </dependencies>
 <configuration>
 <verbose>true</verbose>
 <complianceLevel>1.5</complianceLevel>
 <source>1.5</source>
 <showWeaveInfo>true</showWeaveInfo>
 <outxml>true</outxml>
 <aspectLibraries>
   <aspectLibrary>
     <groupId>org.springframework</groupId>
     <artifactId>spring-aspects</artifactId>
   </aspectLibrary>
 </aspectLibraries>
 </configuration>
 </plugin>

2 个答案:

答案 0 :(得分:2)

使用Spring的aop配置,您可以获得一定的抽象和便利,另一方面,Spring需要在类加载期间做很多工作来生成动态代理并编织类。这在启动时总是有开销。

然而,服务器启动时间很少是关键因素,您倾向于以天为单位测量正常运行时间,因此在我看来,一分钟左右的启动速度对于所有方便都是公平交易,尽管它可能会令调试失败。

如果向服务器启动添加一些进程来运行应用程序,则可以稍微减轻首次加载的开销。这有助于确保服务器已准备就绪,因此您的第一个真实请求不会受到影响。

如果您必须更快地启动或发现不可接受的开销,您可以考虑使用编译时编织来实现切入点。通过这种方法,繁重的工作都是在编译时完成的,因此类的加载时间与无纺布版本相当(取决于编织的当然情况)。

答案 1 :(得分:0)

当我分析堆栈跟踪时,我自己找到了答案。

除了@Configurable with CTW,我用于事务管理。当我第一次加载带有@Configurable注释的原型bean时,spring bean factory会检查我们的aop:advices是否匹配。因此它使用了一个aspectj库。

所以我原来的问题有点误导。我们在@Configurable中使用CTW,但同时使用LTW进行事务和安全管理。然后必须在加载时再次编译在编译时编织的bean。

我现在将寻找一种避免LTW的方法,因为启动时间对我们的开发过程至关重要。

感谢您的意见和解答。当他们把我推向正确的方向时,他们很有帮助。