2

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

我正在运行一个应用程序

  • 春天 2.5.x
  • 可配置的注释
  • 编译时编织 (CTW)
  • 行家
  • 日食/ajdt

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

查看第一次调用的分析器堆栈跟踪,我发现 org.aspectj.weaver.internal.tools.PointcutExpressionImpl.matchesMethodExecution(Method) 使用了 93% 的时间

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

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

但似乎只有当有人在这个类上调用 new 时,Spring 才开始分析原型 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>
4

2 回答 2

2

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

然而,服务器启动时间很少是一个关键因素,您倾向于以天为单位来衡量正常运行时间,因此在我看来,为了方便起见,一分钟左右的启动速度是一个公平的交易,尽管它可能对调试目的很烦人。

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

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

于 2009-07-16T18:44:20.563 回答
0

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

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

所以我最初的问题在某种程度上具有误导性。我们将 CTW 用于 @Configurable,但同时使用 LTW 进行事务和安全管理。在编译时编织的 bean 必须在加载时再次编织。

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

感谢您的评论和回答。他们很有帮助,因为他们把我推向了正确的方向。

于 2009-07-20T09:26:46.407 回答