【问题标题】:Spring AOP not working in web-application on tomcat 8Spring AOP在tomcat 8上的Web应用程序中不起作用
【发布时间】:2018-04-30 10:39:46
【问题描述】:

我想在我的应用程序中使用 Spring AOP 来记录一些日志内容。我已经在一个独立的应用程序中使用了 AOP,它可以工作,但现在在 tomcat 上的一个 web 应用程序它不能工作。

我有一个 application-core 和一个 application-web 项目,在 core 项目中所有的逻辑都发生了,而 web-project 只包含与 web 相关的东西。

首先,我尝试将我的 LoggingAspect 类添加到我的核心项目中,因为这不起作用,我现在将它移到 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 类,现在位于: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;
        }

    }

我还在我的应用程序网络项目中添加了一个类

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

}

我期望的是,每个被调用的方法都会被记录,但那不会发生。

【问题讨论】:

  • 如果您希望组件扫描检测到您的方面,则需要为@Component。它还需要在您为组件扫描指定的包中。
  • 我已经添加了@Component 但它也没有工作,方面是我在 componentsscan 中定义的包内。我通过破坏一些切入点语法来尝试这样做,在这里我收到一些“切入点格式不正确的异常”,所以我猜我的 LoggingAspect 已加载,但不知何故它没有激活?
  • 请公开您的@Around 建议。春天需要找到它。如果这还不够,还请公开切入点。如果两者都不够,请在公开方面中的每个方法后告诉我,如果将completePackage() 切入点更改为execution(* *(..)),会发生什么?
  • 在更改切入点时,您是否按照我所说的那样除了公开所有内容?你的目标类也是组件吗?您是否曾经基于一个示例项目在您的 Tomcat 上运行过 任何 Spring-AOP 方面?可能你有一些配置问题。如果所有这些猜测(无论如何我都不喜欢)没有帮助,请编辑您的问题并提供MCVE,最好准备好在 GitHub 上使用 Maven 进行克隆和构建。
  • 我刚刚看到了 Gretty 的评论。在我用谷歌搜索之前我什至不知道它是什么,所以我不能说任何关于它的智能。也许对初学者来说保持简单并手动启动 Tomcat 以排除其他可能的错误源。运行最简单的设置,然后对其进行优化和自动化。这样你就会发现哪里出了问题。如果您刚刚开始使用一项新技术,那么在激活所有花里胡哨的情况下进行调试可能有点过于雄心勃勃。

标签: java tomcat spring-aop


【解决方案1】:

Al Phaba 写道:

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

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

我的解决方案有点令人失望,我此时停止了我的功能分支,因为它目前正在努力解决它,正如我所读到的,你的回答建议我需要通过 LTW 切换到 AspectJ。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我不得不说我有点失望,因为你将我的 cmets 蚕食到你自己的答案中。你找到了我的另一个答案,很好。但即使在我之前的评论中,我也明确问过你的目标课程是否是@Components,而在我醒来并告诉你这就是问题所在之前,你说不。如果您已经回答了您的问题并窃取了我的观点,您能否至少描述一下您为解决问题所做的工作?你有没有例如在 Spring 配置中通过 LTW 从 Spring 切换到 AspectJ?看,这正是我想要一个 MCVE 来回答你的问题的原因。
    • 很抱歉让你失望了,你真的很有帮助,我很感激你的回答。我尝试了您描述的所有内容,并通过这些答案并阅读了一些文档得出了这个结论。我的解决方案有点令人失望,我此时停止了我的功能分支,因为它目前正在努力解决它,正如我所读到的,你的回答建议我需要通过 LTW 切换到 AspectJ。你可以发布一个答案,我会接受它作为解决方案(我不想偷任何东西),我想你可以比我更好地总结这个话题。再次感谢您
    • 感谢您接受我的回答。所以现在请删除这个多余的答案和我们所有的 cmets。整个问题+答案看起来更干净,更少冗余。
    猜你喜欢
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2016-12-11
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    相关资源
    最近更新 更多