在其他JAR中定义时,不会执行Spring Aspect

时间:2012-04-18 06:55:43

标签: spring aspectj spring-aop

我有一个由两个子项目组成的项目,这两个子项目都是Spring项目,每个项目都有一个applicationContext.xml。

一个是框架项目(最终作为JAR),一个是实际的应用程序(最终作为WAR并依赖于JAR并将JAR的applicationContext.xml导入到它自己的applicationContext.xml中)。 / p>

在框架项目中,我为所有公共方法定义了一个方面。

@Aspect
@Configurable
public class MyAspect {

    @Autowired
    private SomeBean mBean;

    @Pointcut("execution(public * *(..))")
    public void anyPublicMethod() {
    }

    @Before("anyPublicMethod()")
    public void checkAuthorization(JoinPoint pJoinPoint) {
        mBean.doSomething();
    }
}

我已经在框架的applicationContext.xml中激活了AOP(由实际应用程序项目的applicationContext.xml导入)。

...
    <context:spring-configured />

    <context:component-scan base-package="com.mypackage" />

    <aop:aspectj-autoproxy/>
...

在框架项目中进行测试时,在Spring bean上调用公共方法时,方面会按预期执行。

如上所述,框架项目作为依赖项包含在应用程序项目中,但在任何Spring bean上调用应用程序项目中的匹配方法(任何公共)时,不会执行该方面。

我也尝试过使用方面的XML配置。这导致了同样的行为。

4 个答案:

答案 0 :(得分:4)

恕我直言,你可以稍微调整一下这个方法。

我要做的第一件事就是将战争的应用程序上下文配置委托给web.xml:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/classes/spring*.xml</param-value>
</context-param>

其次我会在war文件的应用程序上下文中启用aop,因为这是你想要使用它的地方。听起来,就像你正在使用aop配置导入应用程序上下文只是为了在你的web项目中获取它,这可能是错误的。

最后我假设这些是运行时而不是编译方面,在后一种情况下,无论依赖性如何,都需要在war项目中使用aspectj重新编译。

答案 1 :(得分:1)

Spring MVC webapps中,实际上有2个上下文:根上下文和servlet的上下文。请务必在 servlet 的上下文中配置您的方面。实际上,servlet的上下文“看到”了根目录 - 而不是相反:

  

在Web MVC框架中,每个DispatcherServlet都有自己的   WebApplicationContext,它继承了已定义的所有bean   根WebApplicationContext。这些继承的bean可以   在特定于servlet的范围内重写,您可以定义新的   给定Servlet实例本地的特定于范围的bean。

因此,如果您希望将方面应用于其bean,则必须在[servlet-name]-servlet.xml文件中而不是在其他文件中导入框架配置。

答案 2 :(得分:0)

这就是我的所作所为:

<context:annotation-config/>
<context:component-scan base-package="my.pkg" scoped-proxy="interfaces"/> 
<aop:aspectj-autoproxy proxy-target-class="true" />

虽然我不知道它是否适用于您的情况......如果您在github上设置项目的精简版本会有所帮助。

这不需要任何字节码编织或检测jvm。只需确保在调用相关方法时使用自动注入属性,即

@Autowired
private MyType myTypeInstance; // MyType is usually an interface

public void someMethod() {
    // myTypeInstance is actually a proxy object... thereby providing the
    // access point for the weaving stuff. (as far as I understand it)
    myTypeInstance.method();
}

否则,如果您不喜欢弹簧管理的AOP类代理,请关注these instructions

答案 3 :(得分:0)

我认为你需要让你的方面成为春天认可它的一个组成部分:

http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/aop.html#aop-at-aspectj

  

通过组件扫描自动检测方面

     

您可以注册   方面类作为Spring XML配置中的常规bean,或   通过类路径扫描自动检测它们 - 就像其他任何一个一样   Spring管理的bean。但请注意,@ Aspect注释不是   足以在类路径中自动检测:为此,你   需要添加一个单独的@Component注释(或者是一个   自定义构造型注释,符合规则   Spring的组件扫描仪。)