springboot之aop面向切面处理

AOP:何为AOP 

aop全称Aspect Oriented Programming,面向切面,AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。其与设计模式完成的任务差不多,是提供另一种角度来思考程序的结构,来弥补面向对象编程的不足。

  通俗点讲就是提供一个为一个业务实现提供切面注入的机制,通过这种方式,在业务运行中将定义好的切面通过切入点绑定到业务中,以实现将一些特殊的逻辑绑定到此业务中。

  比如,若是需要一个记录日志的功能,首先想到的是在方法中通过log4j或其他框架来进行记录日志,但写下来发现一个问题,在整个业务中其实核心的业务代码并没有多少,都是一些记录日志或其他辅助性的一些代码。而且很多业务有需要相同的功能,比如都需要记录日志,这时候又需要将这些记录日志的功能复制一遍,即使是封装成框架,也是需要调用之类的。在此处使用复杂的设计模式又得不偿失。

  所以就需要面向切面出场了。


搭建例子如下:

  • 创建自定义标签
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface KeyCache {
    Class<?> type();//被代理类的全类名,在之后会做为redis hash 的key
}
  • 创建切面编程
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
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;

@Component
@Aspect
public class jaspect {
    private static final Logger logger =  Logger.getLogger(jaspect.class);

    ThreadLocal<Long> startTime = new ThreadLocal<Long>();

    @Pointcut("execution(* com.example.aop.controller.AopController.*(..))")// 定义切点表达式
    @Order(2)
    public void controllerPoint() {
    }

    @Pointcut("@annotation(com.example.aop.annotation.KeyCache)")// 定义注解类型的切点,只要方法上有该注解,都会匹配
    @Order(1)
    public void annotationPoint(){

    }

    // 定义前置通知
    @Before("annotationPoint()")
    public void before(JoinPoint joinPoint) {
        System.out.println("方法执行前执行.....before");
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        logger.info("<====================================================================");
        logger.info("请求来源:  => " + request.getRemoteAddr());
        logger.info("请求URL: " + request.getRequestURL().toString());
        logger.info("请求方式: " + request.getMethod());
        logger.info("响应方法: " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        logger.info("请求参数 : " + Arrays.toString(joinPoint.getArgs()));
        logger.info("---------------------------------------------------------------------");
        startTime.set(System.currentTimeMillis());
    }

    @Around("controllerPoint() && args(arg)")// 需要匹配切点表达式,同时需要匹配参数
    public String around(ProceedingJoinPoint pjp, String arg) {
        System.out.println("name:"+arg);
        System.out.println("方法环绕start....around.");
        String result = null;
        try {
            result = (String) pjp.proceed()+" aop String";
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("方法环绕end.....around");
        return result;
    }

    @After("within(com.example.aop.controller.*Controller)")
    public void after() {
        System.out.println("方法之后执行....after.");
    }

    @AfterReturning(pointcut="controllerPoint()", returning="rst")
    public void afterReturning(JoinPoint joinPoint, Object rst) {
        System.out.println("方法执行完执行.....afterReturning");
        logger.info("耗时(毫秒) : " + (System.currentTimeMillis() - startTime.get()));
        //logger.info("返回数据: {}", String.valueOf(rst));
        logger.info("====================================================================>");
    }

    @AfterThrowing("within(com.example.aop.controller.*Controller)")
    public void afterThrowing() {
        System.out.println("异常出现之后.....afterThrowing");
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值