Различия в обозначениях 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()