Spring AOP - 如何使父上下文中定义的方面在子上下文中工作?
Posted
技术标签:
【中文标题】Spring AOP - 如何使父上下文中定义的方面在子上下文中工作?【英文标题】:Spring AOP - How to make aspects defined in a parent context work in child contexts? 【发布时间】:2013-07-24 13:52:37 【问题描述】:在我的 web.xml 文件中,我有:
<!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
上下文配置位置 类路径:共享上下文.xml
<!-- Main general mapping, i.e. context for the UI & version queries --> <servlet> <servlet-name>mainDispacherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:web-application-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mainDispacherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- Processes application requests for version 1 --> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:version-api-contexts/application-context[v1.0].xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/api/v1.0/*</url-pattern> </servlet-mapping>
在父上下文中,shared-context.xml
,我有:
<aop:aspectj-autoproxy/>
<context:component-scan base-package="com.company.cse.support.audit"/>
包com.company.cse.support.audit
包含一个标有@Component 的类和
@方面。
这方面会在我的审核日志中记录一条消息。
当我在子上下文version-api-contexts/application-context[v1.0].xml
中定义的 bean 上调用方法时,spring AOP 不会代理 bean,并且不会调用方面。
如果我移动方面定义行<context:component-scan base-package="com.company.cse.support.audit"/>
对于子上下文 XML,方面工作正常。
我最终会有很多子上下文,我不想在每个子 XML 文件中都放置这一行。 有没有办法在父上下文中定义共同方面并让它们在子上下文中工作?
【问题讨论】:
【参考方案1】:Spring AOP 代理的创建发生在通过 bean 后处理器加载上下文时。由于子上下文仅在父上下文已加载后才被加载,因此在父上下文中定义的 bean 后处理器不可能影响子上下文中的 bean。
如果您希望子上下文中的 bean 被代理,您必须确保两件事:
-
子上下文可以访问方面 bean(可以将它们放在父上下文中)
执行代理本身的 bean 后处理器包含在上下文中
对于#2,每个子上下文定义中都需要<aop:aspectj-autoproxy/>
。如果您想避免重复,请尝试将所有子上下文共有的部分分解到一个单独的 xml 文件中,您可以依次导入每个文件中。
【讨论】:
【参考方案2】:简而言之,<aop:aspectj-autoproxy/>
是一种 bean 后处理器,bean 后处理器只能影响加载在同一上下文或其父上下文中的方面 bean。
bean 后处理器不可能影响子上下文中的 bean(这些 bean 在父 bean 后处理器之后初始化)。
【讨论】:
以上是关于Spring AOP - 如何使父上下文中定义的方面在子上下文中工作?的主要内容,如果未能解决你的问题,请参考以下文章