如何在springmvc中正确使用aspectj来实现打印日志?

我想通过写自定义注解来实现打印一个方法的执行时间,使用的是老项目中的

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

依赖,项目使用的是springmvc结构,
注解类:

package com.data.annotation;

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

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecTime {
    String value() default ""; // 方法描述参数,默认为空
}

切面类:

package com.data.annotation.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MethodExecutionTimeAspect {

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


    @Pointcut("@annotation(com.data.annotation.LogExecTime)")
    public void logPointCut() {
    }

    @Around("logPointCut()") // 使用@Around注解
    public Object logMethodExecTime(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        long startTime = System.currentTimeMillis();
        Object result = joinPoint.proceed(); // 执行目标方法
        long endTime = System.currentTimeMillis();
        long executionTime = endTime - startTime;
        logger.info("================【{}】执行时间:【{}】ms=================", methodName, executionTime);
        return result; // 返回目标方法的执行结果
    }
}

spring-mvc的配置文件里开启了:

<aop:aspectj-autoproxy proxy-target-class="true" />

我的测试Controller类:

import com.data.annotation.LogExecTime;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;

@RequestMapping("/myTest")
@Controller
public class TestController implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Autowired
    private TestService testService;

    @RequestMapping("/test")
    @ResponseBody
    @LogExecTime
    public void test(){
        TestController controller = (TestController) applicationContext.getBean("testController");
        controller.test2();
        testService.test3();
    }

    @LogExecTime
    public void test2(){
        System.out.println("test2");
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

我的测试Service类:

import com.data.annotation.LogExecTime;
import org.springframework.stereotype.Service;

@Service
public class TestService {

    @LogExecTime
    public void test3(){
        System.out.println("test3");
    }
}

一开始只有test方法上的注解能够生效,后来查阅资料发现需要使用代理对象去调用test2方法才能让test2方法上的注解生效,确实成功了,可是现在我发现注入的方法test3上的注解一直没有生效,网上的教程都是主要注入了testService调用注解就能正常生效,我又怀疑是不是没有注入成功导致的?可是没有注入成功代码应该是跑都跑不起来的?有没有大神给点思路或者说给出调用service里方法上注解生效的其他方法?

阅读 2.3k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题