Spring AOP 在 tomcat 8 上的 Web 应用程序中不起作用

Spring AOP not working in web-application on tomcat 8

我想在我的应用程序中使用 Spring AOP 进行一些日志记录。我已经在一个独立的应用程序中使用了 AOP 并且它可以工作,但是现在在 tomcat 上使用网络应用程序它不起作用。

我有一个应用程序核心和一个应用程序网络项目,核心项目中发生了所有逻辑,而网络项目仅包含与网络相关的内容。

首先我尝试在我的核心项目中添加我的 LoggingAspect class,因为这不起作用我现在将它移到 Web 项目但是尽管它不起作用。

这是我的 applicationContext.xml,它在文件夹中:/application-web/src/main/webapp

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">

        <!-- Add AspectJ autoproxy support for AOP -->
        <aop:aspectj-autoproxy/>


        <!-- Step 3: Add support for component scanning -->
        <context:component-scan base-package="my.foobar"/>

        <!-- Step 4: Add support for conversion, formatting and validation support -->
        <mvc:annotation-driven/>

        <!-- Step 5: Define Spring MVC view resolver -->
        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/view/" />
            <property name="suffix" value=".jsp" />
        </bean>
    </beans>

这是我的 LoggingAspect class 现在位于:application-web/src/main/my.foobar.web/aspects/LoggingAspect

    @Aspect
    @Order(1)
    public class LoggingAspect {
        private static final LogHandler LOG = LogHandler.getLogger(LoggingAspect.class);

        @Pointcut("execution(* my.foobar.*.*.*(..))")
        private void completePackage(){}

        @Pointcut("execution(* my.foobar.*.*.get*(..))")
        private void getterMethods(){}

        @Pointcut("execution(* my.foobar.*.*.set*(..))")
        private void setterMethods(){}

        @Pointcut("completePackage() && !(getterMethods() || setterMethods())")
        private void allMethodsExceptGetterAndSetter(){}

        @Around("completePackage()")
        private Object aroundMethod(ProceedingJoinPoint theProceedingJointPoint) throws Throwable{
            LOG.info("around method");
            String method = theProceedingJointPoint.getSignature().getName();
            Object[] arguments = theProceedingJointPoint.getArgs();

            LOG.info("method call: {0}", method);                
            for(Object arg: arguments){
                LOG.info("argument[{0}]", arg);
            }

            Object result = theProceedingJointPoint.proceed();
            return result;
        }

    }

我还向我的应用程序 Web 项目添加了一个 class

@Configurable
@EnableAspectJAutoProxy
@ComponentScan("my.foobar")
public class ApplicationWebAppConfig {

}

我期望的是,每个被调用的方法都会被记录下来,但事实并非如此。

我想我解决了我的问题。我想我可以在我的应用程序中只使用 spring-aop 作为一个独立的功能。我正在添加一些 JSP 页面并第一次使用 spring-mvc,在此期间我看到 spring-aop 并想为什么不使用它来对我的方法进行一些额外的测量。我的示例独立应用程序工作得非常好,这就是为什么我试图将其适应我现有的应用程序。但是问题就在这里开始了,我想测量的方法与 spring 无关,所以从@kriegaex 发布到这里 这是行不通的

Al Phaba 写道:

I think I figured out my problem. I thought I could use just spring-aop as a standalone feature in my application. I was adding some JSP pages and used for this the first time spring-mvc and during this I saw spring-aop and thought why not using this for some additional measurements of my methods. My sample standalone application worked really good thats why i tried to adapt this to my existing application. But here the problem starts, the methods which I want to measure are not spring related so as posted from kriegaex this is not working.

是的,Spring 依赖动态代理(默认情况下 JDK 代理 class 实现接口,class 不实现接口的 CGLIB 代理,以及这些代理仅适用于 Spring 组件,因为只有那些在连接应用程序时才会被 Spring 代理。然而,AspectJ 直接编织到原始 class 的字节码中,并且也可以应用于非 Spring classes,只要它们在激活 AspectJ 时尚未加载(例如JRE classes).

My solution is a bit disappointing I stopping my feature branch at this point because it currently to much effort to solve it, as I read and you answer suggest I need to switch to AspectJ via LTW.

好吧,如果您的应用程序已经在运行,如果操作正确,只需几分钟即可将配置从 Spring AOP 更改为 AspectJ,如 Spring manual 中所述。我鼓励您尝试一下,这真的没有那么难。祝你好运。