项目中引入 Spring AOP 但不生效的解决方法

来源:互联网 发布:php post数组长度限制 编辑:程序博客网 时间:2024/05/21 14:46

1 发现问题

打算使用 Spring AOP 做切面实现记录日志的功能。因为注解方式比较简单,所以采用注解来实现。

1、在 spring 的配置文件中加入了以下配置:

<!-- 扫描包下所有的类,让标注Spring 注解的类生效 --><context:component-scan base-package="com"/><!-- 开启对 @Aspect 的支持--><aop:aspectj-autoproxy/>

2、新增了切面类:

@Component@Aspectpublic 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;    }}

3、新建了注解类:

public @interface SysLog {    /**     * 描述     *     * @return     */    public String description();}

4、然后,在相应的方法上加入了该注解:

@RequestMapping(value = "/save")@ResponseBody@SysLog(description = " xxx")public AjaxResponse save(DictItem dictItem) {}

然而,项目在实际运行时,没有打印出切面的日志!

2 分析

打开 log4j 的 DEBUG 选项,发现系统并没有调用切面方法!

建一个单元测试试一试吧:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = {"classpath:spring-context.xml"})@TransactionConfiguration(defaultRollback = true)@Transactionalpublic class BeanAspectTest {    @Autowired    private DictItemController dictItemController;    @Test    public void aspect() {        DictItem dictItem=new DictItem();        dictItem.setDictItemIsOptional("true");        dictItem.setDictItemDescription("1");        dictItem.setDictItemValue("1");        dictItem.setDictItemType("health");        dictItemController.save(dictItem);    }}

在单元测试中,可以打印出切面日志,这说明 spring 框架配置的 AOP 运行正常!那么,为什么系统运行时就不正常了呢?

比较单元测试用到的配置文件与系统运行的配置文件,在有一点上不同,即系统运行时使用到了 spring 的 MVC 配置文件。spring 的 MVC 是独立的配置文件,所以 Controller 的配置都在这个文件中,应该把 AOP 的配置移到这里。

3 解决问题

把原有的配置移动到 spring 的 MVC 配置文件中:

<!-- 扫描包下所有的类,让标注Spring 注解的类生效 --><context:component-scan base-package="com"/><!--配置注解驱动--><mvc:annotation-driven/><!-- 开启对 @Aspect 的支持--><aop:aspectj-autoproxy/>

重启后,运行系统,AOP 恢复正常啦:

开始before()...结束

记住,如果项目用了 spring MVC,一定要把 AOP 的相关配置移动到 MVC 配置文件哦O(∩_∩)O~

扫描包下所有的路径配置以及注解驱动配置也可以一并移过来,统一管理。

原创粉丝点击