【问题标题】:Spring AOP with Around advice and @annotation not working带有环绕建议和@annotation 的 Spring AOP 不起作用
【发布时间】:2022-04-17 04:02:55
【问题描述】:

我正在使用 Spring AOP 登录我的应用程序。这是 applicationContext.xml 文件

<mvc:annotation-driven />
<context:component-scan base-package="com.template" />
<context:annotation-config />
<jpa:repositories base-package="com.template.repository"/>
<tx:annotation-driven />

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/template?autoReconnect=true"/>
    <property name="username" value="root"/>
    <property name="password" value=""/>
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
    <property name="persistenceUnitName" value="template"/>

</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

我的 aopLogging.xml 是

<bean id="aopLogging" class="com.template.log.AopLoggingAspect" />
<aop:aspectj-autoproxy proxy-target-class="false"/>

我的 Aspect 类是

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
public class AopLoggingAspect {

private static final Logger logger = Logger.getLogger(AopLoggingAspect.class);

@Around(value="@annotation(com.template.log.Loggable)")
public Object logAround(final ProceedingJoinPoint joinPoint) throws Throwable{
        Object retVal = null;
        try {
            StringBuffer startMessageStringBuffer = new StringBuffer();

            startMessageStringBuffer.append("Start method execution :: ");
            startMessageStringBuffer.append(joinPoint.getSignature().getName());
            startMessageStringBuffer.append("(");

            Object[] args = joinPoint.getArgs();
            for (int i = 0; i < args.length; i++) {
                startMessageStringBuffer.append(args[i]).append(",");
            }
            if (args.length > 0) {
                       startMessageStringBuffer.deleteCharAt(startMessageStringBuffer.length() - 1);
            }

            startMessageStringBuffer.append(")");
            logger.info(startMessageStringBuffer.toString());
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            retVal = joinPoint.proceed();
            stopWatch.stop();

            StringBuffer endMessageStringBuffer = new StringBuffer();
            endMessageStringBuffer.append("Finish method ");
            endMessageStringBuffer.append(joinPoint.getSignature().getName());
            endMessageStringBuffer.append("(..); execution time: ");
            endMessageStringBuffer.append(stopWatch.getTotalTimeMillis());
            endMessageStringBuffer.append(" ms;");

            logger.info(endMessageStringBuffer.toString());
        } catch(Exception ex) {
            StringBuffer errorMessageStringBuffer = new StringBuffer();
            logger.error(errorMessageStringBuffer.toString(), ex);
            throw ex;
        }
        return retVal;
}
}

我的自定义注释是

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Loggable {
}

我的服务类是

public class UserService {
@Transactional(readOnly=true)
@Loggable
public User getUserByUserId(Long userId){
return userRepository.findOne(userId);
}
}

问题是日志没有被打印出来。请帮我。提前致谢。如果需要任何其他信息,请告诉我。

【问题讨论】:

    标签: java spring annotations aop


    【解决方案1】:

    在我看来,您似乎忘记在您的applicationContext.xml 文件中导入aopLogging.xml 文件。尝试将此添加到您的 applicationContext.xml 文件中:

    <!-- Import your AspectJ config -->
    <import resource="classpath:aopLogging.xml" />
    

    【讨论】:

    • 嗨,我已经尝试过了,但它也不起作用。此外,当我使用相同的配置运行测试用例时,它工作得非常好。但是当我将相同的配置战部署到 tomcat 时,它并没有拦截方法。有什么线索吗?
    • 注意:: 我的所有应用程序都没有使用接口。
    【解决方案2】:

    创建注释

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)

    公共@interface LogExecutionTime { }

    然后是一个方面

    @Aspect

    @组件
    公共类 LoggingAspect {

    然后是Aspect中的一个方法

    @Around("@annotation(LogExecutionTime)")
    公共对象 logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {

      long start = System.currentTimeMillis();
    
      Object proceed = joinPoint.proceed();
    
      long executionTime = System.currentTimeMillis() - start;
    
      LOGGER.info(joinPoint.getSignature() + " executed in " + executionTime + "ms");
      return proceed;     }
    

    然后使用 Annotation Anywhere

    @PostMapping(value="/signup")
    @LogExecutionTime
    公共@ResponseBody ResponseObject注册(用户用户){ }

    【讨论】:

      【解决方案3】:

      试试这个..

      @Around(value="@annotation(Loggable)")
      public Object logAround(final ProceedingJoinPoint joinPoint) throws Throwable{
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多