Spring AOP медленное время запуска - PullRequest
6 голосов
/ 14 января 2011

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

Я провел некоторое профилирование и обнаружил, что большую часть времени тратится во время инициализации контейнера Spring, более конкретно org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory) - занимает около 35 секунд. org.springframework.aop.support.AopUtils.canApply(Pointcut, Class, boolean) - занимает около 15 сек.

Моя цель - запустить приложение через 5-10 секунд, а не через ~ 45 секунд, как сейчас, поэтому любые советы будут высоко оценены.

Ответы [ 6 ]

5 голосов
/ 19 января 2011

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

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

  1. Удалите нотацию <aop:aspectj-autoproxy/> из вашего файла контекста.
  2. Добавьте шаг компиляции aspectJ в файл сборки. На сайте AspectJ вы сможете найти плагин ant,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" />
4 голосов
/ 03 октября 2017

У меня была та же проблема, оказывается, что проксирование в Spring AOP тратит МНОГО времени на загрузку классов с помощью bcel (без кэширования, поэтому загружая снова и снова те же классы, как java.lang.Object ...), когдапытаясь выяснить, какие советы применяются.Его можно несколько улучшить, написав более точные срезы точек (используйте внутри, например, @within), но я нашел решение, которое работало бы лучше, если бы все ваши точки были написаны с помощью @ annotation.

1)Деактивируйте авто-прокси с помощью: spring.aop.auto = false

2) Напишите собственный подкласс AnnotationAwareAspectJAutoProxyCreator для фильтрации bean-компонентов, которые должны быть оформлены в соответствии с вашими собственными критериями, например, этот основан на пакете и аннотациях:

@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 секунд.

Надеюсь, это поможет кому-то и белым медведям

3 голосов
/ 14 января 2011

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

1 голос
/ 18 января 2011

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

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

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

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

1 голос
/ 14 января 2011

Я не уверен, что это применимо к вашей ситуации, но Производительность Spring может быть улучшена с помощью CachingBeanFactory .

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

0 голосов
/ 19 декабря 2012

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

...