Различия в обозначениях Spring Pointcut (в зависимости от исполнения)

Пожалуйста... кто-нибудь может объяснить мне, в чем разница между использованием следующих обозначений пружинных точек?

Использование "внутри указателя точки":

<aop:pointcut expression="within(my.app.dao.impl.*)" id="commonDaoOperation"/>

Используя "указатель точки выполнения":

<aop:pointcut expression="execution(public * my.app.dao.impl.*.*(..))" id="commonDaoOperation"/>

Я использую второй в своих веб-проектах (и я думаю, что он наиболее часто используется), проблема, которую я нашел с этим подходом, состоит в том, что он потребляет много памяти в куче...

Проанализировав "дамп кучи" сервера приложений с помощью "анализатора памяти eclipse", я обнаружил, что мое приложение потребляет 450 МБ и экземпляры класса "org.springframework.aop.aspectj.AspectJExpressionPointcut"потребляют 30% из этих 450 МБ...

Каждый экземпляр AspectJExpressionPointcut занимают 6 МБ (приблизительно), и это потому, что каждый экземпляр содержит кэш совпадений с экземплярами java.lang.reflect.Method и, что удивительно, кешируется много java-методов (методов, которые не упоминаются в моем выражении pointcut).

После прочтения документации Spring я решил использовать первый подход (в обозначении pointcut), а теперь каждый экземпляр AspectJExpressionPointcut занимают гораздо меньше памяти.

Вопрос об этом... в чем разница в производительности между ними...

Спасибо заранее...

3 ответа

Документация Spring объясняет разницу:

  • выполнение - для сопоставления точек соединения выполнения метода это основной указатель точки, который вы будете использовать при работе с Spring AOP
  • в пределах - сопоставление точек соединения в определенных типах (просто выполнение метода, объявленного в сопоставлении типов при использовании Spring AOP)

Другими словами, execution соответствует методу и within соответствует типу.

В этом случае ваши точки в значительной степени эквивалентны. Ваш within соответствует любому типу в пакете my.app.dao.impl и ваш execution соответствует всем открытым методам любого типа в пакете my.app.dao.impl,

Тем не мение, execution Я думаю, что он реализован с перехватчиком для каждого подходящего метода (много объектов), который within нужен только один перехватчик, так как он соответствует всему типу (очень мало объектов).

execute () сопоставляет точки соединения, которые являются выполнением метода. Это единственный указатель, который фактически выполняет совпадения. Все остальные обозначения (поддерживаемые Spring AOP) ограничивают только эти совпадения. Обратите внимание, что Spring поддерживает только подмножество указателей, доступных в AspectJ (Spring AOP основан на прокси). AspectJ указатели точек, которые поддерживаются в Spring: args() и @args(), target() и @target(), Within () и @within(), execute (), this(), @annotation

Как упоминалось здесь :

  • execution()- сопоставить сигнатуру метода joinPoint
  • within()- сопоставить все методы JoinPoint в данном классе, пакете или подпакете

Другие существующие типы выражений pointcut:args(),target(),this(),@args(),@within(),@target(),@annotation()

Другие вопросы по тегам