Spring Boot系列04-AOP配置

阅读这篇博文时,假定读者已经掌握了Spring Boot+maven开发应用的入门技巧
初次接触Spring Boot,那也没关系,移步Spring Boot + maven 开发的入门教程
10分钟完成你的第一个Spring Boot应用

1. 使用的核心技术

动态代理

没有接触过设计模式的同学,请移步设计模式02-动态代理模式
先了解动态代理设计模式,有助于理解Spring AOP的原理

2. Java Maven项目需要的pom依赖

<dependency>                              
     <groupId>org.springframework.boot</groupId>                    
     <artifactId>spring-boot-starter-aop</artifactId>  
</dependency> 

3. 切面Aspect类定义

PointCut(切点)+Advice(通知)

package driver.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class WebControllerAop {
    //匹配driver.controller包下的所有无参方法
    //  @Pointcut("execution(* driver.controller..*.*(..))")
    public void executeService0() {
    }

    //匹配driver.controller.WebController类下的所有无参方法
    @Pointcut("execution(* driver.controller..WebController.*())")
    public void executeService() {
    }

    /**
     * 前置通知,方法调用前被调用
     * 
     * @param joinPoint
     */
    @Before("executeService()")
    public void doBeforeAdvice(JoinPoint joinPoint) {
        System.out.println("Before通知");
    }

    // 方法体执行后,在方法return返回值前执行
    @After("executeService()")
    public void doAfterAdvice(JoinPoint joinPoint) {
        System.out.println("After通知");
    }

    // 方法return返回值之后执行,需要对方法返回值做加工的可以用此通知
    @AfterReturning(value="executeService()",returning="keys")  
    public void doAfterReturningAdvice1(JoinPoint joinPoint,Object keys){  
        System.out.println("AfterReturning通知");  
    }  

    //环绕通知,方法执行前后都可以增加处理逻辑,
    //值得注意的是,环绕通知方法的切点必须用ProceedingJoinPoint
    @Around("executeService()")
    public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
        System.out.println("环绕通知执行方法前");
        try {// obj之前可以写目标方法执行前的逻辑
            Object obj = proceedingJoinPoint.proceed();// 调用执行目标方法
            System.out.println("环绕通知执行方法后");
            return obj;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }
}

4. 测试用的目标类定义

1. driver.controller.WebController

package driver.controller;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import driver.config.ConfigHelper;
import driver.service.BootService;

@Controller
public class WebController {
    @RequestMapping(value="/ttt",method=RequestMethod.GET)
    @ResponseBody
    public String ttt(){
        return "ttt";
    }
}

运行main方法,启动Spring Boot,
浏览器访问 http://localhost:8080/ttt
运行结果:

  1. 浏览器会返回 ttt字符串
  2. 会输出如下日志
    这里写图片描述

2. driver.controller.InterfaceController

package driver.controller;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class InterfaceController {
/**
     * @PathVariable
     */
    @RequestMapping("/path/{name}/{age}")
    @ResponseBody
    public String getNames(@PathVariable("name")String a,@PathVariable("age")int age) {
        //System.out.println("名字是:"+a+",年龄:"+age);
        return "name:"+a+",age:"+age;
    }
}

运行main方法,启动Spring Boot,
浏览器访问 http://localhost:8080/path/xiaoming/20

运行结果:
1. 浏览器返回字符串: name:xiaoming,age:20
但是不会有上述截图的AOP相关日志

总结

使用Spring Boot开发应用时,通过Spring提供的AOP能力,
在执行跟切点匹配的方法时,能把通用的前置、后置处理跟具体的业务逻辑实现分离、解耦

举两个特别常用且有效的应用场景:
1. 方法执行前后记日志
2. 事务控制

本篇博文旨在引导读者基于Spring Boot使用AOP功能,
具体的知识点,如PointCut/Advice定义等,用到时自行查阅资料。

猜你喜欢

转载自blog.csdn.net/wwhrestarting/article/details/78379727
今日推荐