2011-01-14 4 views
5

Мы используем Spring (3.0.5) АОП с аннотациями @AspectJ и <aop:aspectj-autoproxy/> . Мы используем его для транзакций, аудита, профилирования и т. Д. Он отлично работает, за исключением того, что время запуска приложения постоянно растет по мере добавления большего количества кода.Spring AOP медленное время запуска

Я сделал некоторое профилирование и обнаружил, что большую часть времени тратится на инициализацию контейнера весны, а точнее 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 вызывает трогания является поспешный вывод. (С учетом плетение происходит во время выполнения). Вы проверяли статистику JVM с помощью Jconsole или visualVm. У вас есть собственный метод init для некоторых из ваших компонентов. Вы пытались использовать ленивую инициализацию. (по свойству lazy-init в bean-компоненте)? –

+0

Эти шаги я последую за ними. 1- Проверяйте статистику JVM при нормальной загрузке. 2. Сделайте свойство lazy-init beans по умолчанию, а затем снова проверьте статистику jvm (использование памяти и др.). 3- Если все еще нет заметного улучшения, я затем остановлю аспект автопроксимирования. Как я уже говорил, если бы мне пришлось сделать ставку, я буду готов поспорить, что это не AOP-соткание, влияющее на время загрузки. –

+0

Я уверен, что это плетение, так как я потратил много времени на профилирование с помощью Yourkit, беря только потоки дампов во время запуска и размещения точек останова и всех точек плетения АОП. Но мне любопытно, когда вы говорите об отключении аспект аутопроверки, что альтернатива, которую вы предлагаете? Спасибо, Yuval –

ответ

1

У меня была такая же проблема, оказалось, что автопроксирование Spring AOP тратит много времени при загрузке классов загрузки с помощью bcel (без кэширования, поэтому загрузка снова и снова таких же классов, как java.lang.Object ...) при попытке выяснить, какие советы применяются. Это может быть несколько улучшено путем написания более мелкозернистых разрезов точек (используйте внутри, например, @within), но я нашел решение, которое сработало лучше, если все ваши pointcuts написаны с помощью @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; 
    } 
} 

В моем случае время запуска от 60 до 15 с.

Я надеюсь, что это поможет кому-то и полярные медведи

1

Я не уверен, что это относится к вашей ситуации, но Spring performance can be improved by empolying a CachingBeanFactory.

Обычно это относится к проводным компонентам, но в зависимости от того, как ваши аспекты применяются и проводятся, это может привести к улучшению.

+0

Спасибо, я проверю это. –

+0

Я пробовал этот метод, он не помог –

2

Видимо, это известная проблема, если у вас много неэлементных бобов. Кажется, что исправление для пружины 3.1: https://jira.springsource.org/browse/SPR-7328

+0

Спасибо за ссылку, это, вероятно, не так, большинство наших бобин - это одноточие, но это, скорее всего, связано. –

+0

К сожалению, использование кешированных AopUitls не помогло ни –

1

У вас есть круговая зависимость? Вот что убивает мое текущее приложение.

Я знаю, что это не решение, но я бы разложил контекст, чтобы запускать разные службы в разных vms, SOA-стиле. Это должно позволить всем вашим приложениям иметь небольшое время запуска, что также должно дать вам некоторую гибкость для более простого изменения этих служб, небольшого количества кода для тестирования и т. Д.

Я не делал этого в одно из моих приложений и теперь время запуска составляет около 3/4 минут, что является безумным (у нас есть пара тысяч бобов). Эта проблема не исчезнет, ​​она только ухудшится, но если вы попытаетесь что-то сделать с ней слишком поздно, приложение будет слишком большим и слишком сложным для разрыва.

Еще одна вещь, которую я бы рассмотрел, - это спящий режим, создание фабрики сеансов может быть довольно медленным.

+0

Спасибо за советы, откуда вы знаете, что с круговой зависимостью является то, что убивает приложение? –

+0

Какую IDE вы используете? например, Intellij IDEA имеет круговой анализ зависимостей в своих опциях меню «Анализ». –

5

От того, что вы опубликовали, похоже, что вы используете Time Time Weaving, которое несет штраф за запуск, потому что система должна сплести все классы по мере их загрузки. Если основной проблемой является время запуска, то я предлагаю вам переключиться на Compile Time Weaving. Вы можете найти инструкции о том, как это сделать в весенней документации (глава 6, раздел 8) или на сайте AspectJ (http://www.eclipse.org/aspectj/docs.php)

Переключение на компиляцию время ткачество с компилятором AspectJ относительно stragiht вперед:

  1. Снимите <aop:aspectj-autoproxy/> обозначения из файла контекста.
  2. Добавить aspectJ компилировать шаг к вашей сборке файл. На сайте AspectJ вы должны сможете найти муравейный плагин, В кодехахе есть плагин 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> 

Для 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" /> 
+0

Спасибо за подсказку, но переход на компиляцию - это не вариант, люди, с которыми я работаю, сильно против шагов после компиляции. –

+1

@Yuval: можете ли вы хотя бы попробовать, чтобы подтвердить, что временное переплетение вызывает задержку? –

+0

@Bruno: Я дал ему первую попытку, и это не сработало гладко, но я буду работать над этим еще, когда у меня будет больше времени и отчет, спасибо. –

0

У меня была такая же проблема, прежде чем я изменить jdk1.7 обратно jdk1.6. По jdk1.7 мое приложение зависает на «Инициализация корня Spring WebApplicationContext» в течение более 30 секунд. После того, как я вернусь, он запустится за 10 секунд.

Смежные вопросы