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

Dor*_*old 2 java spring 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>
Run Code Online (Sandbox Code Playgroud)

contextConfigLocation类路径:shared-context.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>
Run Code Online (Sandbox Code Playgroud)

在父上下文中shared-context.xml,我有:

 <aop:aspectj-autoproxy/>

 <context:component-scan base-package="com.company.cse.support.audit"/>
Run Code Online (Sandbox Code Playgroud)

该包com.company.cse.support.audit包含一个标有@Component和@Aspect的类.此方面将消息记录到我的审核日志中.

当我在子上下文中定义的bean上调用一个方法时version-api-contexts/application-context[v1.0].xml,bean不会被spring AOP代理,并且不会调用该方面.如果我将方面定义行移动<context:component-scan base-package="com.company.cse.support.audit"/> 到子上下文XML,则方面可以正常工作.

我最终会有很多子上下文,我不想将这一行放在每个子XML文件中.有没有办法在父上下文中定义一次公共方面并让它们在子上下文中工作?

zag*_*gyi 6

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

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

  1. 子上下文可以访问方面bean(在父上下文中使用它们可以)
  2. 执行代理的bean后处理器包含在上下文中

对于#2,您将需要<aop:aspectj-autoproxy/>在每个子上下文定义中.如果您想避免重复它,请尝试将所有子上下文共有的部分分解为单独的xml文件,然后您可以在每个文件中导入它们.