【学习笔记】Spring中的面向切面编程
首先要在pom.xml文件中引入aop的依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
编写切面类,作用在带有@GetMapping注解的方法上
import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component public class AOP { @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)") private void logAdvicePointcut(){ } @Before("logAdvicePointcut()") public void logBeforeAdvice(){ System.out.println("GetMapping注解的前置通知"); } @After("logAdvicePointcut()") public void logAfterAdvice(){ System.out.println("GetMapping注解的后置通知"); } }
@Aspect注解表示当前类是一个切面类。@Pointcut注解用来标志一个切点,即定义的通知在何处切入到业务代码中。@Before和@After分别是前置通知和后置通知的注解,里面的值为切点的方法名。
在定义切点时,常用的方式有两种,分别是注解和路径表达式的方式。上述代码用的是注解@annotation的方式,路径表达式的用法以execution(* com.mutest.controller..*.*(..)))为例:
-
第一个 * 号的位置:表示返回值类型,* 表示所有类型。 包名:表示需要拦截的包名,后面的两个句号表示当前包和当前包的所有子包 第二个 * 号的位置:表示类名,* 表示所有类。 *(..):这个星号表示方法名,* 表示所有的方法,后面括弧里面表示方法的参数,两个句号表示任何参数。
也可以省去@Pointcut注解,直接在@Before里面写,比如:
-
@Before("@annotation(org.springframework.web.bind.annotation.GetMapping)") @Before(value=“execution(* com.mutest.controller….(…)))”)
编写Controller:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class AOPController { @GetMapping("/getTest") @ResponseBody public String getTest() { System.out.println("getMapping注解对应的controller执行"); return "Success"; } }
@ResponseBody注解作用是让返回的字符串直接在网页上显示。
启动程序并在浏览器访问localhost:8080/getTest,控制台中打印出以下信息:
GetMapping注解的前置通知 getMapping注解对应的controller执行 GetMapping注解的后置通知