问题5: spring+自定义注解+aop完成日志记录

目标: 创建自定义注解,在方法上使用自定义注解完成该方法被调用后日志的记录

问题: 1:自定义注解和aop如何关联到一起

         2:使用aop过程中几点不注意导致切面无法调用


一:配置自定义注解和切面  完成日志记录

    1.定义自定义的注解

@Target({ElementType.PARAMETER, ElementType.METHOD}) //定义注解可以使用的范围
@Retention(RetentionPolicy.RUNTIME)    //定义注解生效的时间
@Documented
public @interface LogAnno{}    //可以在注解体中定义自己想自定义的字段,一般定义 在该切入点的方法执行什么操作等信息  比如: add操作,  菜单

    2.切面

    spring配置文件(我使用注解事务,没有配置手动事务管理)

<!--开启注解扫描->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 注解方式配置事物 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!--启用cglib代理创建切面-->
<aop:aspectj-autoproxy proxy-target-class="true"/>

    切面类

@Aspect
@Component
public class MyLoggerAspect {

    @Autowired
    private LoggerService loggerService;    //注入loggerService是使用loggerService中的方法将日志录入数据库

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

    @Pointcut("@annotation(com.wenwuxiaoxue.managementUI.annotation.LogAnno)")
    public void controllerAspect(){}    //这个地方是自定义注解和切面类结合的点

    /*@Before("controllerAspect()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("--------before------");
        if(logger.isInfoEnabled()){
            logger.info("before " + joinPoint);
        }
    }
    //后置通知
    @Around("controllerAspect()")
    public void doAround(JoinPoint joinPoint){
        System.out.println("--------doAround------");
        if(logger.isInfoEnabled()){
            logger.info("doAround " + joinPoint);
        }
    }*/

    @After("controllerAspect()")
    public void doAfter(JoinPoint joinPoint){
        System.out.println("--------doAfter------");
        if(logger.isInfoEnabled()){
            logger.info("doAfter " + joinPoint);
        }
        loggerService.addSysLog(new SysLog(),new HashMap<String,Object>());
    }
}

 切面类描述: 使用@Aspect注解将该类定义成一个切面类,@Component使spring可以扫描到(也可以在配置文件里使用<bean>进行定义,或者使用@Configuration注解类进行定义)

 @Pointcut定义了切入的方式, 在这个地方我使用了定义一个方法,然后在该方法上使用这个注解,然后在前置/后置/环绕等通知上直接使用这个方法名称就可以了,相当于抽取出来了.当然你可以直接把@Pointcut里面的内容写到通知方法上.

这样就完成了注解和通知的整合,使用的时候只需要在对应的方法上使用自定义注解就可以了


注意点:1 如果前台是ajax请求,你又是通过controller中的方法直接return回去的,而你的自定义注解或者切面类正好在controller的方法上,那么切面是不会生效的.

(不知道把响应ajax的方法写入到拦截器中会不会解决切面失效问题.没有测试,我一直想将普通请求和ajax请求整合到一个拦截器中,通过判断请求头是否是ajax然后按照不同的方式响应,但是目前还没有实现,也许后面会进行改造)

    2.另外一个失效的地方就是,当你在切面类同时写了前置,环绕,后置通知以后,切面生效的方法后续代码是不执行的,我不知道问题出在哪里,当我只使用后置通知时,方法就恢复正常,所有的数据都会加载出来. 所以在上面的代码中我将前两个通知注释掉了. 下面贴一下失效的图



阅读更多
个人分类: 开发中的错误
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭