面向切面编程的简单应用

​ 面向切片编程在很多项目中都有使用过,使用的场景也是较多。一个东西它之所以存在,肯定是解决了一些实际过程中的问题。要多去思考它存在的意义,就能理解的更深刻,才能举一反三。

​ 为什么会有面向切片编程。程序中最讨厌的事是复制代码,如果你发现同一段代码,或者相似的代码需要在多处出现,就会感觉到明显的“坏味道”。你不得不去维护散落在各个地方的同样逻辑,随着业务的不断复杂或者变更,这令人难以维护。这时有些人就提出来了,这不简单吗,我把这些相同的代码提取成一个方法,然后在需要的地方调用它,就可以减轻维护压力。对于相似的代码,抽象出一个方法兼容几个相似的逻辑,也可以提取出公共的方法。但是你还是需要在你使用的地方去显式的调用它,这对于公共方法的调用者类是耦合的。有没有一种无侵入式的方式,优雅的进行公共逻辑的调用呢,这就是面向切面编程要解决的问题。

​ 面向切面编程(AOP)专门用来解决各个模块中交叉关注点的问题,如事务管理、安全检查、缓存等。话不多说,今天我们讲下面向如何使用面向切片编程进行全局日志记录。

package com.xxx.xxx.component;

import com.alibaba.fastjson.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
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;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Aspect
@Component
public class WebLogAspect {
    private Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    // 定义切入点的名称(如果多个增强处理,可以方便的使用名称)
    @Pointcut("execution(* com.xxx.xxx.controller.*.*(..))")
    public void webLog(){}

    @Around("webLog()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        long startTime = System.currentTimeMillis();
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 记录下请求内容
        logger.info("URL:{},请求开始", request.getRequestURL().toString());
        logger.info("Params : " + Arrays.toString(pjp.getArgs()));
        // result的值就是被拦截方法的返回值
        Object result = pjp.proceed();
        logger.info("URL:{},请求结束,result:{} ", request.getRequestURL().toString(), JSON.toJSONString(result));
        logger.info("Cost Time : {}ms" ,(System.currentTimeMillis() - startTime));
        return result;
    }
}

​ 增强处理类型:before,after,after-returning,after-throwing,around

​ 这里简单的举了一个全局日志的例子,实际中使用起来很简单方便。这里就会有同学又有疑问了:拦截器和AOP有什么区别呢?

​ 拦截器主要是拦截url的请求,进行请求的分发及路由,到真正的处理类。aop主要拦截spring中Bean的生命周期的访问,aop使用的是代理模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值