Spring @Configurable 与编译时编织的启动性能
这是我关于堆栈溢出的第一个问题,所以请友善。
我正在运行一个带有
- spring 2.5.x
- 可配置注释
- 编译时编织 (CTW)
- maven
- eclipse/ajdt 的
应用程序我使用 CTW,一切运行正常。 但是,如果我第一次实例化带注释的类,则需要很长时间。 第二次就非常快了。
查看第一个调用的探查器堆栈跟踪,我看到 93% 的时间被使用 org.aspectj.weaver.internal.tools.PointcutExpressionImpl.matchesMethodExecution(Method)
在第二次调用的堆栈跟踪中,此方法仅使用了 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>
this is my first question on stack overflow, so please be kind.
i am running an app with
- spring 2.5.x
- Configurable Annotations
- Compile time weaving (CTW)
- maven
- eclipse/ajdt
I use CTW and everything runs fine. But if i instantiate an annotated class for the first time it takes very long. the second time it is very fast.
Looking at the profiler stack trace for the first call i saw 93% of the time is used by
org.aspectj.weaver.internal.tools.PointcutExpressionImpl.matchesMethodExecution(Method)
In the stack trace of the second call only 1% of the time is used in this method. Even worse: first call takes about 10 times as long as the second call.
I was wondering as i thought a weaver is no longer needed with CTW.
But it seems that Spring starts analyzing the prototyped bean only as soon as someone calls new on this class. It uses aspectj weaver to analyze what needs to be done and prepares itself to speed up this process for the next call.
Does anybody has any experience with speeding up the first call of initializing an annotated class?
this is a snippet of my 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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过 Spring 的 aop 配置,您可以获得一定程度的抽象性和便利性,但另一方面,Spring 需要在类加载期间做大量工作来生成动态代理并编织类。 这在启动时总是会产生开销。
然而,服务器启动时间很少是一个关键因素,您倾向于以天为单位来衡量正常运行时间,因此在我看来,为了方便起见,一分钟左右的启动速度是公平的,尽管出于调试目的可能会很烦人。
如果您向服务器启动添加一些进程来运行应用程序,则可以在一定程度上减轻首次加载的开销。 这有助于确保服务器已准备就绪,因此您的第一个实际请求不会受到影响。
如果您确实必须更快地启动或发现开销不可接受,您可以考虑使用编译时编织来实现切入点。 通过这种方法,繁重的工作都在编译时完成,因此类的加载时间与未编织版本相当(当然取决于编织的作用)。
With Spring's aop configuration you gain a measure of abstraction and convenience, the flip side is that Spring needs to do a lot of work during class loading to generate the dynamic proxies and weave the classes. This will always have an overhead at startup.
However server startup time is rarely a critical factor, you tend to measure uptime in days, so a minute or so slower startup is a fair trade for all the convenience in my opinion, though it might be annoying for debugging purposes.
You can mitigate the overhead of first-time loading somewhat if you add some processes to the server startup to exercise the application. This helps ensure the server is primed, so your first real request doesn't take the hit.
If you do have to startup quicker or find the overhead unacceptable, you might consider implementing the pointcuts with compile-time weaving. With this approach the heavy lifting is all done at compile time so the classes are loaded in a comparable time to the unwoven versions (depending on what the weaving does of course).
当我分析堆栈跟踪时,我自己找到了答案。
除了 @Configurable 和 CTW 之外,我还使用它来进行事务管理。 当我的带有 @Configurable 注释的原型 bean 第一次加载时,spring bean 工厂会检查我们的 aop:advices 是否匹配。 因此它使用aspectj库。
所以我原来的问题在某种程度上具有误导性。 我们将 CTW 用于 @Configurable,但同时使用 LTW 进行事务和安全管理。 在编译时编织的 bean 必须在加载时再次编织。
我现在将寻找一种完全避免 LTW 的方法,因为启动时间在我们的开发过程中至关重要。
感谢您的评论和回答。 他们很有帮助,因为他们把我推向了正确的方向。
I found the answer by my self when i analyzed the stack trace.
In addition to @Configurable with CTW I am using for transaction management. When my prototype bean annotated with @Configurable is loaded for the first time, spring bean factory checks to see if any of our aop:advices match. Therefore it uses an aspectj library.
So my original question was somehow misleading. We are using CTW for @Configurable, but using LTW at the same time for transaction and security management. The bean weaved at compile-time must then be weaved again at load time.
i will now look for a way to avoid LTW at all, as startup time is critical in our development process.
Thanks for your comments and answers. They were helpful as they pushed me into the right direction.