Spring AOP之Controller层AOP实现日志功能

前言

在项目中我们需要知道那个用户那个ip请求了那个接口,我们需要将日志写入数据库,来监控哪些功能在哪个时间段被哪些模块调用。这里使用的是spring AOP结合注解对Controller进行切面。

一、导入jar

对于基础包这里没有列出
    <!--aop所依赖的包-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>

二、编写注解类


/**
 *自定义注解 拦截Controller
 */
@Target({ElementType.PARAMETER, ElementType.METHOD}) //作用范围为方法和参数
@Retention(RetentionPolicy.RUNTIME) //指定生命周期为内存可读
@Documented //指定其为注解
public @interface SystemControllerLog {
    /**
     * 操作说明
     */
    public String description() default "";

}

三、编写切面类


/**
 * 切点类
 * @author tiangai
 * @since 2014-08-05 Pm 20:35
 * @version 1.0
 */
@Aspect
public  class SystemLogAspect {

    //注入Service用于把日志保存数据库
    @Resource
    private LogService logService;
    //本地异常日志记录对象
    private  static  final Logger logger = Logger.getLogger(SystemLogAspect.class);


    //Controller层切点
    @Pointcut("@annotation(com.hsy.aspect.SystemControllerLog)")
    public  void controllerAspect() {}


    @AfterReturning(pointcut="controllerAspect()",returning="obj")
    public void myAfterReturning(JoinPoint joinPoint,Object obj) {
        logger.info("我是Controller层的返回通知");
        logger.info("拿到返回的数据---->"+obj);
        logger.info("拿到Controller注解描述"+ getControllerMethodDescription(joinPoint));
    }

    /**
     * 获取注解中对方法的描述信息 用于Controller层注解
     *
     * @param joinPoint 切点
     * @return 方法描述
     * @throws Exception
     */
    public  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        String description = "";
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
                    description = method.getAnnotation(SystemControllerLog. class).description();
                    break;
                }
            }
        }
        return description;
    }

}

四、配置springmvc.xml

这里有一个坑一定要是springmvc不能是spring
    <!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller -->
    <aop:aspectj-autoproxy proxy-target-class="true" />

    <!-- 使用了@AspectJ注解的切面类 -->
    <bean class="com.hsy.aspect.SystemLogAspect"/>

五、在Controller层加入自定义注解

@RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    //此处为记录AOP拦截Controller记录用户操作
    @SystemControllerLog(description = "登录账号")
    public String selectUser(@RequestBody(required=true) Map<String,String> map  ) throws Exception {
    
    return "test";
 }

六、测试

在Postman中进行测试

成功

猜你喜欢

转载自www.cnblogs.com/shaoyu/p/11882712.html