请...有人能解释一下使用以下弹簧切入点指示符之间的区别吗?
使用“切入点指示符”:
<aop:pointcut expression="within(my.app.dao.impl.*)" id="commonDaoOperation"/>
使用“执行切入点指示符”:
<aop:pointcut expression="execution(public * my.app.dao.impl.*.*(..))" id="commonDaoOperation"/>
我在我的网络项目中使用第二个(我认为它是最常用的),我用这种方法发现的问题是它在堆中消耗了大量内存......
在使用“eclipse内存分析器”分析应用程序服务器的“堆转储”后,我发现我的应用程序消耗了450 MB而类"org.springframework.aop.aspectj.AspectJExpressionPointcut
的实例占用了450 MB的30% ...
AspectJExpressionPointcut
的每个实例占用6 MB(大约),这是因为每个实例都保留了与java.lang.reflect.Method实例匹配的缓存,并且令人惊讶的是有很多java方法被缓存(方法)我的切入点表达没有提到。)
阅读Spring文档后,我决定使用第一种方法(在切入点指示符内),现在AspectJExpressionPointcut
的每个实例占用的内存都少得多。
问题在于......他们之间的表现差异是什么......
非常感谢...
答案 0 :(得分:4)
Spring documentation解释了差异:
- 执行 - 对于匹配方法执行连接点,这是您在使用Spring AOP时将使用的主要切入点指示符
- - 限制匹配某些类型中的连接点(只需执行在匹配类型中声明的方法) 使用Spring AOP)
换句话说,execution
匹配方法,within
匹配类型。
在这种情况下,您的切入点几乎相同。您的within
与包my.app.dao.impl
中的任何类型匹配,而您的execution
与包my.app.dao.impl
中任何类型的所有公共方法相匹配。
然而,我认为execution
是为每个匹配的方法(很多对象)实现的拦截器,within
只需要一个拦截器,因为它匹配整个类型(非常小的对象) )。
答案 1 :(得分:0)
execution()匹配作为方法执行的连接点。这是实际执行比赛的唯一指示者。所有其他指示符(受Spring AOP支持)仅限制那些匹配。 请注意,Spring仅支持AspectJ中可用的指定子集(Spring AOP基于代理)。 Spring支持的AspectJ切入点指示符是: args()和@args(),target()和@target(),inside()和@within(),execution(),this(),@ annotation