有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Spring AOP切入点表达式中对包名的java通配符支持

我正在尝试实现一个可以跨应用程序中的多个包应用的记录器方面。它是一个大型spring web应用程序,有许多模块。每个模块都有自己的控制器、服务和DAO。我定义的切入点针对包中每个类上的所有公共方法。它是public * com.abc.module1.controllers.*.*(..)用于控制器,public * com.abc.module1.services.*.*(..)用于服务,public * com.abc.module1.daos.*.*(..)用于模块1中的DAO。我有大约30个这样的模块。所以问题是,为了涵盖所有这些模块,我必须为每个模块定义切入点。所有模块都遵循相同的包结构。有没有一种方法可以指定切入点,它可以覆盖放置在不同模块中的所有controllersservices?spring AOP是否允许在包名中使用通配符


共 (1) 个答案

  1. # 1 楼答案

    我确实建议你阅读AspectJ documentation,例如

    那么你就不需要在这里问这样的问题了

    不管怎样,以下是解决问题的方法(我添加了换行符以提高可读性):

    execution(public * com.abc..controllers..*(..)) ||
    execution(public * com.abc..services..*(..)) ||
    execution(public * com.abc..daos..*(..))
    

    或者:

    (
      within(com.abc..controllers..*) ||
      within(com.abc..services..*) ||
      within(com.abc..daos..*)
    ) &&
    execution(public * *(..))
    

    如果您使用Spring AOP而不是成熟的AspectJ,您可以让它变得更简单,因为Spring AOP基本上只知道execution(),而不知道其他切入点,比如call()、构造函数执行、set()/get()等等

    within(com.abc..controllers..*) ||
    within(com.abc..services..*) ||
    within(com.abc..daos..*)
    

    对于JDK动态代理(组件实现接口时的默认设置),无论如何,这只会以公共方法调用为目标。有了CGLIB代理,它还可以针对受保护的代理并打包私有代理。顺便说一句,如果您以后从Spring AOP迁移到AspectJ,您还需要将简单切入点升级到上述更明确的切入点之一