您当前的位置: 首页 >  spring

梁云亮

暂无认证

  • 1浏览

    0关注

    1211博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

SpringBoot 集成AOP

梁云亮 发布时间:2020-05-31 20:57:12 ,浏览量:1

第一步:创建SpringBoot项目,导入Maven依赖

    org.springframework.boot
    spring-boot-starter-web


    org.springframework.boot
    spring-boot-starter-test
    test


    org.springframework.boot
    spring-boot-starter-aop


    javax.servlet
    javax.servlet-api
    4.0.1

第二步:创建一个Aspect切面类并在其中定义好切点
@Aspect
@Component
public class WebControllerAop {
    //匹配com.hc.controller包及其子包下的所有类的所有方法
    @Pointcut("execution(public * com.hc.controller..*.*(..))")
    public void executeService()
    {
    }
}
第三步:创建一个Controller请求处理类
@RestController
@RequestMapping("/aop")
public class WebController {
}
第四步:具体测试 前置通知:方法执行之前被调用 配置前置通知:
@Before("executeService()")
 public void doBeforeAdvice(JoinPoint joinPoint) throws JsonProcessingException {
    System.out.println("前置通知!!!");
    Signature signature = joinPoint.getSignature(); //通知的签名
    System.out.println(signature.getName()); //代理的是哪一个方法
    //获取RequestAttributes
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    //从获取RequestAttributes中获取HttpServletRequest的信息
    HttpServletRequest request = (HttpServletRequest) 
	requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
    Object[] obj = joinPoint.getArgs();//获取目标方法的参数信息
    System.out.println(Arrays.toString(obj));
    if(obj.length > 0) {
        Enumeration enumeration = request.getParameterNames();
        Map parameterMap =  new HashMap();
        while (enumeration.hasMoreElements()){
            String parameter = enumeration.nextElement();
            parameterMap.put(parameter,request.getParameter(parameter));
        }
        ObjectMapper om  = new ObjectMapper();
        String str =  om.writeValueAsString(parameterMap);
        System.out.println("请求的参数信息为:"+str);
    }
}
在Controller类里添加一个请求处理方法来测试前面的前置通知,具体代码如下:
@RequestMapping("/fun1")
public String fun1(@RequestParam Integer deptno, @RequestParam String dname, @RequestParam String loc) {
    System.out.println(deptno + " " + dname + " " + loc);
    return deptno + " " + dname + " " + loc;
}

启动项目,然后在浏览器中请求http://localhost/aop/fun1?deptno=10&dname=sales&loc=boston时,结果如下图所示: 在这里插入图片描述

后置返回通知:在方法正常返回结果之后执行 配置后置返回通知:
@AfterReturning(value = "execution(public * com.hc.controller..*.*(..))",returning = "keys")
public void doAfterReturningAdvice1(JoinPoint joinPoint,Object keys){
    System.out.println("后置返回通知的返回值:"+keys);
}

@AfterReturning(value = "execution(public * com.hc.controller..*.*(..))",returning = "keys",argNames = "keys")
public void doAfterReturningAdvice2(String keys){
    System.out.println("后置返回通知的返回值:"+keys);
}
在Controller类里添加请求处理方法来测试前面的后置返回通知:
@RequestMapping("/fun21")
public String fun21(String key){
    return "key=: "+key;
}
@RequestMapping("/fun22")
public Integer fun22(Integer key){
    return key;
}

启动项目,然后在浏览器中请求http://localhost/aop/fun21?key=asdf 时,结果如下图所示;请求时,结果如下图所示: 在这里插入图片描述 在这里插入图片描述

后置异常通知:在方法抛出异常之后执行 配置后置异常通知:
@AfterThrowing(value = "executeService()",throwing = "exception")
public void doAfterThrowingAdvice(JoinPoint joinPoint,Throwable exception){
    System.out.println("目标方法名:"+joinPoint.getSignature().getName());
    if(exception instanceof NullPointerException){
        System.out.println("发生了空指针异常!!!!!");
    }
}
在Controller类里添加请求处理方法来测试前面的后置返回通知,具体代码如下:
@RequestMapping("/fun3")
public String fun3(String key){
    throw new NullPointerException();
}

启动项目,然后在浏览器中请求http://localhost/aop/fun3?key=asdf 时,结果如下图所示: 在这里插入图片描述

后置最终通知:在方法执行之后执行 配置后置最终通知:
@After("executeService()")
public void doAfterAdvice(JoinPoint joinPoint){
    System.out.println("后置通知执行了!!!!");
}
在Controller类里添加请求处理方法来测试前面的后置返回通知,具体代码如下:
@RequestMapping("/fun41")
public String fun41(String key){
    throw new NullPointerException();
}
@RequestMapping("/fun42")
public String fun42(String key){
    return key;
}

启动项目,然后在浏览器中请求http://localhost/aop/fun41?key=asdf 时,结果如下图所示;请求http://localhost/aop/fun44?key=asdf 是,结果如下图所示: 在这里插入图片描述 在这里插入图片描述

环绕通知:围绕着方法执行 配置环绕通知:
@Around("execution(public * com.hc.controller..*.fun*(..))")
public Object doAroundAdvice(ProceedingJoinPoint pjp){
    Object res = null;
    System.out.println("目标方法的名称:"+pjp.getSignature().getName());
    System.out.println("目标方法的参数:"+Arrays.toString(pjp.getArgs()));
    try {
        System.out.println("环绕通知--前置");
        res = pjp.proceed();//调用目标方法
        System.out.println("环绕通知--返回值:" + res);
    } catch (Throwable throwable) {
        System.out.println("环绕通知--异常");
        throw new RuntimeException(throwable);
    }
    System.out.println("环绕通知--后置");
    return res;
}
在Controller类里添加请求处理方法来测试前面的后置返回通知,具体代码如下:
@RequestMapping("/fun5")
public int fun5(int num1, int num2) {
    return num1 + num2;
}

启动项目,然后在浏览器中请求http://localhost/aop/fun5?num1=123&num2=321时,结果如下图所示: 在这里插入图片描述

关注
打赏
1665409997
查看更多评论
立即登录/注册

微信扫码登录

0.0436s