views:

745

answers:

2

Hi

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>
+1  A: 

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).

Rich Seller
A: 

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.

Janning