Spring——AOP原理初探(为你的Spring项目添加统一的日志)

首先,AOP是一种编程范式,是一种思想,是为了将通用逻辑从业务逻辑中分离出来,并且不写过多重复代码

这样做的好处是:1.可以集中处理某一关注点;2.可以方便的添加删除关注点;3.增强代码可读性,更加便于维护

他有如下几种应用场景:1.权限控制(用户登录,及用户权限可调用的接口等);2.缓存控制;3.事务控制;4.审计日志;5.性能监控;6.分布式追踪;7.异常处理

分享我在springboot项目中两种利用AOP模式添加日志的方法:

第一种利用@Aspect注解:

/**
 * AOP实例(@Aspect作用是把当前类标识为一个切面供容器读取)
 *
 * @Author: liangxiao
 * @Date: Created in 0:41 2018/5/25
 */
@Aspect
@Component
public class HttpAspect {

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

    @Pointcut("execution(public * com.liangxiao.demo.controller.GirlController.*(..))")
    public void log() {
    }

    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //url
        logger.info("url={}", request.getRequestURL());

        //method
        logger.info("method={}", request.getMethod());

        //ip
        logger.info("ip={}", request.getRemoteAddr());

        //类方法
        logger.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());

        //参数
        logger.info("args={}", joinPoint.getArgs());

    }

    @After("log()")
    public void doAfter() {
        logger.info("2222222222222222222");
    }

    @AfterReturning(returning = "object",pointcut = "log()")
    public void doAfterReturning(Object object){
        logger.info("response={}",object.toString());
    }
}

第二种实现HandlerInterceptor接口,并重写对应的方法:

/**
 * 日志拦截器
 *
 * @author:liangxiao
 * @date:2018/6/7
 */
@Component
public class LogInterceptor implements HandlerInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(LogInterceptor.class.getName());
    @Autowired
    protected RequestLogger requestLogger;

    public static final String ANALYSIS_STRING = "@@ANALYSIS@@";

    public static final String REQUEST_START_TIMESTAMP = "start_time";

    private static final String ATTRIBUTE_HTTP_COST = "cost";

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        request.setAttribute(REQUEST_START_TIMESTAMP,
                System.currentTimeMillis());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        Object name = request.getAttribute(ConstantUtil.REQUEST_CATEGORY);
        if (name == null) {
            return;
        }
        long cost = System.currentTimeMillis() - (Long) request.getAttribute(REQUEST_START_TIMESTAMP);
        request.setAttribute(ATTRIBUTE_HTTP_COST, cost);

        //vaquero log
        LOGGER.info(ANALYSIS_STRING + " " + name + ".cost=" + cost + "ms");
        //analyzer log
        requestLogger.log((String) name, request, response);
    }
}

这个需要在用WebMvcConfigurerAdapter配置一下,配置类如下:

/**
 * 拦截器配置
 * @author:liangxiao
 * @date:2018/6/7
 */
@Configuration
@EnableWebMvc
public class InterceptorConfig extends WebMvcConfigurerAdapter {
    @Autowired
    private LogInterceptor logInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(logInterceptor).addPathPatterns("/**");
    }
}

如上我只是对Spring的AOP有初步的使用,进一步的优劣对比和原理,我将在后续的学习和使用中继续添加到我后续的博客中~

    原文作者:AOP
    原文地址: https://blog.csdn.net/sinat_35752979/article/details/80619305
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞