2011-01-14 147 views
5

我们使用的是Spring(3.0.5)AOP,@AspectJ样式注释和<aop:aspectj-autoproxy/> 。我们将它用于交易,审计,分析等。它可以很好地工作,只是随着更多代码的添加,应用程序的启动时间不断增长。Spring AOP慢启动时间

我已经做了一些分析,发现大部分时间都花在Spring容器初始化期间,更具体地说是org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory) - 大约需要35秒。 org.springframework.aop.support.AopUtils.canApply(Pointcut, Class, boolean) - 大约需要15秒。

我的目标是让应用程序在5-10秒内启动,而不是像现在这样启动约45秒,因此任何提示都将非常感谢。

+0

跳转到结论的Spring AOP导致启动性能匆忙的结论。(考虑到编织在运行时发生)。您是否使用Jconsole或visualVm检查了JVM的统计信息。你有一些自定义的init方法吗?你有没有尝试使用延迟初始化。 (通过bean中的lazy-init属性)? – 2011-01-21 05:46:19

+0

这些是我将遵循的步骤。 1-正常加载时检查JVM统计信息。 2.将bean lazy-init属性设置为默认值,然后再次检查jvm stat(内存使用率等)。 3-如果仍然没有显着的改善,我会关闭方面autoproxying。就像我刚才提到的那样,如果我必须下注,我会准备好下注,它不会影响加载时间的AOP编织。 – 2011-01-21 05:46:34

+0

我非常确定这是编织,因为我花了很多时间用Yourkit进行分析,在启动时只采用线程转储,并将一些断点和所有点放在AOP编织中。但是当你说关机方面autoproxying你建议的选择是什么时,我很好奇?谢谢,尤瓦尔 – 2011-01-22 22:10:58

回答

1

我有同样的问题,结果发现Spring AOP自动代理花了很多时间用bcel启动加载类(没有缓存,所以再次加载相同的类,比如java.lang.Object ...)当试图找出哪些建议适用。 通过编写更细粒度的点切割(例如,在@within中使用)可以稍微改进,但是如果所有切入点都使用@annotation编写,我发现了一种更好的解决方案。

1)Desactivate自动代理有:spring.aop.auto =假

2)收件AnnotationAwareAspectJAutoProxyCreator的自定义子类来过滤豆类按照自己的标准进行装饰,例如这个人是基于包和注释:

@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; 
    } 
} 

在我的情况下,启动时间从60s降到15s。

我希望这会帮助别人和北极熊

1

你有任何循环依赖?这是什么杀了我目前的应用程序。

我知道这不是一个真正的解决方案,但我会分解上下文以不同的vms运行不同的服务,SOA风格。这应该允许你所有的应用程序有一个小的启动时间,这也应该给你一些灵活性,以更容易地改变这些服务的实现,少量代码来测试等。

我没有那样做我的一个应用程序,现在启动时间约为3/4分钟,这很疯狂(我们有几千个豆子)。这个问题并没有消失,它只会变得更糟,但如果你试图对这件事做得太晚,应用程序将会太大而且难以分解。

我会考虑的另一件事是休眠,创建会话工厂可以很慢。

5

从你发布的内容来看,它看起来像使用加载时织入,因为加载时系统必须编织所有类,所以会引发启动惩罚。如果你主要关心的是启动时间,那么我建议你切换到编译时织入。您可以在春季文档(第6章,第8节)或AspectJ网站(http://www.eclipse.org/aspectj/docs.php)上找到有关如何执行此操作的说明。

切换到编译时间AspectJ编译器织相对stragiht前锋:

  1. 从上下文文件中删除 <aop:aspectj-autoproxy/>符号 。
  2. 添加一个 aspectJ编译步骤到您的版本 文件。在AspectJ网站上,您应该能够找到一个蚂蚁插件 codehaus有一个maven插件。这里 是我们两个人的例子。

对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> 

对于蚂蚁

<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" /> 
0

我有同样的问题,以前我改回jdk1.7到JDK1.6。 由jdk1.7,我的应用程序挂在“初始化Spring根WebApplicationContext”超过30秒。改回来后,它在10秒内启动。