Spring AOP--如何使父上下文中定义的方面在子上下文中工作?

2022-05-08 00:00:00 spring java aspectj spring-aop

在我的web.xml文件中:

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

上下文配置位置 类路径:Shared-Conext.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的类,并且 @Aspect。 此方面会在我的审核日志中记录一条消息。

当我调用子上下文version-api-contexts/application-context[v1.0].xml中定义的Bean上的方法时,该Bean不会被Spring AOP代理,方面也不会被调用。 如果我移动特征定义行<context:component-scan base-package="com.company.cse.support.audit"/> 对子上下文XML来说,方面工作得很好。

我最终将拥有许多子上下文,我不希望在每个子XML文件中都放入该行。 有没有办法在父上下文中定义公共方面,并使它们在子上下文中工作?


解决方案

Spring AOP代理的创建发生在通过Bean后处理器加载上下文的时候。由于只有在加载父上下文之后才加载子上下文,因此父上下文中定义的Bean后处理器不可能影响子上下文中的Bean。

如果希望代理子上下文中的Bean,则必须确保两件事:

  1. 子上下文可以访问方面Bean(将它们放在父上下文中是可以的)
  2. 上下文中包含执行代理本身的Bean后处理器
对于#2,您需要在每个子上下文定义中使用<aop:aspectj-autoproxy/>。如果希望避免重复,请尝试将所有子上下文共有的部分提取到单独的XML文件中,然后可以将该文件导入到每个子上下文中。

相关文章