Spring切点指示器差异(within vs execution)

16

请问有人能够解释一下使用以下Spring切点设计符号的区别吗?

使用“within切点设计符号”:

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

使用“execution pointcut designator”:

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

我在我的Web项目中使用第二种方法(我认为这是最常用的方法),但我发现这种方法会在堆中占用大量内存...

通过使用"eclipse memory analyzer"分析应用程序服务器的"heap dump",我发现我的应用程序正在消耗450 MB的内存,并且类"org.springframework.aop.aspectj.AspectJExpressionPointcut"的实例占用了这450MB的30%...

每个AspectJExpressionPointcut实例占用约6MB的空间,这是因为每个实例都维护着一个与java.lang.reflect.Method实例匹配的缓存,令人惊讶的是,缓存中有很多不被我的切入点表达式提及的java方法。

阅读Spring文档后,我决定使用第一种方法(切入点设计器内部)来解决问题,现在每个AspectJExpressionPointcut实例占用的内存要少得多。

问题是...它们之间的性能差异是什么...

非常感谢您提前的帮助...

3个回答

9

Spring文档解释了它们的不同:

  • execution - 匹配方法执行连接点,这是使用Spring AOP时您将使用的主要切入点设计器
  • within - 限制匹配到某些类型内的连接点(仅在使用Spring AOP时匹配到在匹配类型中声明的方法的执行)

换句话说,execution匹配方法,而within匹配类型。

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

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


@glazaror 使用它们没有实际意义。within 已经匹配了 execution 中的所有内容。 - Sotirios Delimanolis
好的Sotirios Delimanolis,你是正确的...我应该只使用“within”。 - glazaror
在我的“用例”中,“AspectJExpressionPointcut”的实例是由于“execution pointcut designator”而导致内存消耗问题的根源……将其更改为“within pointcut designator”可以减少这个问题。 - glazaror
那么,在某些情况下,使用within pointcut designator是否可以被认为是更好的选择? - glazaror
@glazaror 这并不是“更好”。每个都有其自己的目的。对于您想要实现的内容,within 更加合适。 - Sotirios Delimanolis
显示剩余4条评论

1

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


0
此处所述:
  • execution() - 匹配joinPoint方法的签名
  • within() - 匹配给定类、包或子包中的所有JoinPoint方法

其他现有的切入点表达式类型:args()target()this()@args()@within()@target()@annotation()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接