项目应用:使用自定义注解完成对controller的aop控制

来源:互联网 发布:wkwebview与js交互 编辑:程序博客网 时间:2024/05/22 03:32

在项目进行过程中,需要使用aop对api传入或者传出数据进行日志记录。考虑实际应用,放弃了使用拦截器,转而使用aop的前置通知和返回通知中加入日志记录操作。

在spring中,controller会被JDK自动代理。当使用自定义标签时controller已经实例化不会在通过aop,因此需要走cglib代理。

xml配置:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:p="http://www.springframework.org/schema/p"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:mvc="http://www.springframework.org/schema/mvc"       xmlns="http://www.springframework.org/schema/beans"       xmlns:task="http://www.springframework.org/schema/task"<span style="color:#FF6666;">    <!-- 启动对@AspectJ注解的支持 -->      <aop:aspectj-autoproxy/>          <!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller-->     <aop:aspectj-autoproxy proxy-target-class="true" />  </span><span style="color:#FF6666;">       xmlns:aop="http://www.springframework.org/schema/aop"</span>       xsi:schemaLocation="http://www.springframework.org/schema/mvc        http://www.springframework.org/schema/mvc/spring-mvc.xsd        http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/task        http://www.springframework.org/schema/task/spring-task.xsd<span style="color:#FF6666;">        http://www.springframework.org/schema/aop           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">    <!-- 启动对@AspectJ注解的支持 -->      <aop:aspectj-autoproxy/>          <!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller-->      <aop:aspectj-autoproxy proxy-target-class="true" />  </span>

自定义标签:

package com.xiaoma.universe.video.aspect;import java.lang.annotation.*;@Target({ElementType.PARAMETER, ElementType.METHOD})  @Retention(RetentionPolicy.RUNTIME)  @Documented  public @interface ControllerLog {        String description() default "";//自定义标签属性}

实现aspect:

package com.xiaoma.universe.video.aspect;  import java.lang.reflect.Method;import javax.servlet.http.HttpServletRequest;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;@Aspect  @Component  public  class LogAspect {  //本地异常日志记录对象  private  static  final Logger logger = LoggerFactory.getLogger(LogAspect.class);  //Controller层切点  @Pointcut("@annotation(com.xiaoma.universe.video.aspect.ControllerLog)")public  void controllerAspect() {  }  /**  * 前置通知 用于拦截Controller层记录用户的操作  *  * @param joinPoint 切点  */  @Before("controllerAspect()")  public  void doBefore(JoinPoint joinPoint) {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();System.out.println("请求"+request.getCharacterEncoding());}  /**  * 获取注解中对方法的描述信息 用于Controller层注解  *  * @param joinPoint 切点  * @return 方法描述  * @throws Exception  */  public  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {   Class<?> clazz = joinPoint.getTarget().getClass();String name = joinPoint.getSignature().getName();Object[] parameterTypes = joinPoint.getArgs();for (Method method : clazz.getDeclaredMethods()) {if (method.getName().equals(name) && method.getParameterTypes().length == parameterTypes.length) {ControllerLog methodLog = method.getAnnotation(ControllerLog. class);if (methodLog != null) {return methodLog.description();}break;}}return ""; }  }  
在controller中使用:

@RequestMapping( method=RequestMethod.GET)@ResponseBody@ControllerLog(description="123")public JSONObject list(HttpServletRequest request, HttpServletResponse response ,VideoCourses videoCourses, BaseModel model ,@TokenUser UserInfo user,String channel,String queryType){            return null;        }


0 0
原创粉丝点击