配置了 Spring AOP 但会调用两次的问题解决方法

1 发现问题

项目配置了 Spring AOP,但会被调用两次:

开始
before()
[2017-07-26 11:10:18.071] [INFO]:[com.deniro.jail.service.sys.SysLogAspect][log] [com.deniro.jail.service.sys.SysLogAspect.log(SysLogAspect.java:43)] [调用方法:void com.deniro.jail.service.biz.DictItemService.save(DictItem);输入参数:[com.deniro.jail.domain.biz.DictItem@4f55a864[dictItemId=<null>,dictItemType=health,dictItemDescription=1,dictItemValue=1,dictItemIsOptional=true,createTime=2017-07-26 11:10:18.056,modifyTime=2017-07-26 11:10:18.056]]] 
开始
before()
Hibernate: insert into ...
结束
[2017-07-26 11:10:18.141] [INFO]:[com.deniro.jail.service.sys.SysLogAspect][log] [com.deniro.jail.service.sys.SysLogAspect.log(SysLogAspect.java:58)] [输出参数:null;耗时:0:00:00.062] 
结束

2 分析问题

切面定义如下:

@Component
@Aspect
public class SysLogAspect {

    static Logger logger = LoggerFactory.getLogger(SysLogAspect.class);

    @Pointcut("@annotation(com.deniro.jail.domain.sys.SysLog)")
    private void sysLog() {
    }

    /**
     * 记录日志
     *
     * @param pjp
     */
    @Around("sysLog()")
    public Object log(ProceedingJoinPoint pjp) {

        logger.info("调用方法:{};输入参数:{}", pjp.getSignature()
                , pjp
                .getArgs());

        StopWatch sw = new StopWatch();
        sw.start();
        Object o = null;
        try {
            System.out.println("开始");
            o = pjp.proceed();
            System.out.println("结束");
        } catch (Throwable throwable) {
            logger.error("记录日志", throwable);
        }
        sw.stop();
        logger.info("输出参数:{};耗时:{}", o, sw.toString());
        return o;


    }
}

切点用的是注解配置方式,查了一下,只在一个地方定义了这个注解:

@RequestMapping(value = "/save")
@ResponseBody
@SysLog(description = " 保存【字典项】")
public AjaxResponse save(DictItem dictItem) {
    try {
        dictitemService.save(dictItem);
        return AjaxResponse.success();
    } catch (Exception e) {
        return AjaxResponse.fail();
    }
}

怀疑是重复定义的问题,我们找找看。

打开 spring 的 MVC 配置文件:


<aop:aspectj-autoproxy/>

这是第一处定义的地方,如果类配置了 @Aspect,那么这个类会被自动扫描到 spring 框架中。

第二处定义的地方在 spring 框架配置文件:


<bean class="com.deniro.jail.service.sys.SysLogAspect"/>

难怪被执行了两次呢O(∩_∩)O~

3 解决问题

删除 spring 框架配置文件中定义的切面 bean,好了,现在一切恢复正常咯O(∩_∩)O~

记住:开启了 @Aspect 配置,而且切面类加了 @Aspect 注解,这时就不需要再对切面类进行配置 XML 配置哦。

你可能感兴趣的:(Java,Spring)