弹簧切入指示符差异(内部与执行)

2022-09-03 07:41:51

请。。。谁能解释一下使用下面的弹簧切入点指示符有什么区别?

使用“切入点指示符”:

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

使用“执行切入点指示符”:

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

我在我的Web项目中使用第二个(我认为它是最常用的),我发现这种方法的问题是它在堆中消耗了大量内存......

在使用“eclipse memory analyzer”分析了应用程序服务器的“堆转储”之后,我发现我的应用程序消耗了450 MB,而类“的实例消耗了450MB中的30%..."org.springframework.aop.aspectj.AspectJExpressionPointcut

每个实例占用6 MB(大约),这是因为每个实例都与java.lang.reflect.Method的实例进行了匹配的缓存,令人惊讶的是,缓存了很多java方法(我的pointcut表达式没有提到的方法)。AspectJExpressionPointcut

在阅读了Spring文档之后,我决定使用第一种方法(在切入点指示符内),现在每个实例占用的内存要少得多。AspectJExpressionPointcut

问题就在于此...它们之间的性能有什么区别...

提前致谢...


答案 1

Spring文档解释了其中的区别:

  • 执行 - 对于匹配方法执行连接点,这是您在使用 Spring AOP 时将使用的主要切点指示符
  • within - 限制匹配到某些类型内的连接点(只需在使用 Spring AOP 时执行在匹配类型中声明的方法)

换句话说,匹配方法并匹配类型。executionwithin

在这种情况下,您的切入点几乎是等效的。您匹配包中的任何类型,并且您匹配包中任何类型的所有公共方法。withinmy.app.dao.implexecutionmy.app.dao.impl

但是,我认为,对于每个匹配的方法(很多对象),它只需要一个拦截器,因为它与整个类型(非常小的对象)匹配,因此实现了。executionwithin


答案 2

execution() 匹配作为方法执行的连接点。这是实际执行匹配的唯一指示符。所有其他指示符(由 Spring AOP 支持)仅限制这些匹配项。请注意,Spring仅支持AspectJ中可用的指示符子集(Spring AOP是基于代理的)。Spring中支持的AspectJ切点指示符是:args()和@args(),target()和@target(),within()和@within(),execution(),this(),@annotation


推荐