We're using Spring (3.0.5) AOP with @AspectJ
style annotations and <aop:aspectj-autoproxy/>
. We use it for transactions, auditing, profiling etc. It works fine except that the startup time of the application is continuously growing as more code is being added.
I have done some profiling and found that most of the time is spent during Spring container initialization, more specifically org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory)
- takes about 35 sec.
org.springframework.aop.support.AopUtils.canApply(Pointcut, Class, boolean)
- takes about 15 sec.
My goal is for the application to start in 5-10 seconds and not ~45 sec as it does now, so any tips would be much appreciated.
I had the same issue, it turns out Spring AOP auto-proxying spends a LOT of time at startup loading classes with bcel (without caching, so loading again and again same classes like java.lang.Object...) when trying to figure out which advices apply. It can be somewhat improved by writing more fine-grained Point cuts (use within, @within for example) but I've found a solution that worked better if all your pointcuts are written with @annotation.
1) Desactivate auto-proxy with: spring.aop.auto=false
2) Write a custom subclass of AnnotationAwareAspectJAutoProxyCreator to filter beans to be decorated according to your own criteria, for example this one is based on package and annotations :
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
if (beanClass != null && isInPackages(beansPackages, beanClass.getName()) && hasAspectAnnotation(beanClass)) {
return super.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
} else {
return DO_NOT_PROXY;
}
}
In my case startup time down from 60s to 15s.
I hope it will help someone and polar bears
From what you've posted it looks like your using Load Time Weaving which incurs a startup penalty because the system has to weave all the classes as they are being loaded. If your primary concern is startup time, then I would suggest you switch to Compile Time Weaving. You can find instructions on how to do this in the spring documentation (Chapter 6, Section 8) or in at the AspectJ site (http://www.eclipse.org/aspectj/docs.php)
Switching to Compile time weaving with the AspectJ compiler is relatively stragiht forward:
<aop:aspectj-autoproxy/>
notation
from your context file. For Maven:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
<verbose>true</verbose>
<source>1.6</source>
<target>1.6</target>
<complianceLevel>1.6</complianceLevel>
<showWeaveInfo>true</showWeaveInfo>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
For Ant
<taskdef
resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
<classpath>
<pathelement location="${lib.dir}/AspectJ_1.6.8/aspectjtools.jar"/>
</classpath>
</taskdef>
<iajc aspectPath="${file.reference.spring-aspects.jar}; ${build.classes.dir}/path/to/custom/aspects"
classpath="${lib.dir}/AspectJ_1.6.8/aspectjrt.jar; ${javac.classpath}"
inpath="${build.classes.dir}"
destDir="${build.classes.dir}"
showWeaveInfo="true" />
Apparently this is a known issue if you have a lot of non-singleton beans. There seems to be a fix for Spring 3.1: https://jira.springsource.org/browse/SPR-7328
I am not sure that it applies to your situtation, but Spring performance can be improved by empolying a CachingBeanFactory.
This usually applies when wiring beans, but depending on how your aspects are applied and wired, it might bring improvements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With