1、AOP(面向切面编程)是Spring提供的重要技术工具,其主要功能是对业务层的方法调用进行拦截处理。SpringBoot默认情况下并没有配置AOP拦截器,需要在项目中手动引入spring-boot-starter-aop依赖库后才可以使用。
修改pom.xml配置文件,配置spring-boot-starter-aop依赖库,如下所示:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 5 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 6 <modelVersion>4.0.0</modelVersion> 7 <parent> 8 <groupId>org.springframework.boot</groupId> 9 <artifactId>spring-boot-starter-parent</artifactId> 10 <version>2.3.5.RELEASE</version> 11 <relativePath /> <!-- lookup parent from repository --> 12 </parent> 13 <groupId>com.example</groupId> 14 <artifactId>demo</artifactId> 15 <version>0.0.1-SNAPSHOT</version> 16 <name>demo</name> 17 <description>Demo project for Spring Boot</description> 18 19 <properties> 20 <java.version>1.8</java.version> 21 <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> 22 </properties> 23 24 <dependencies> 25 <dependency> 26 <groupId>org.springframework.boot</groupId> 27 <artifactId>spring-boot-starter-web</artifactId> 28 </dependency> 29 30 <dependency> 31 <groupId>org.springframework.boot</groupId> 32 <artifactId>spring-boot-starter-test</artifactId> 33 <scope>test</scope> 34 <exclusions> 35 <exclusion> 36 <groupId>org.junit.vintage</groupId> 37 <artifactId>junit-vintage-engine</artifactId> 38 </exclusion> 39 </exclusions> 40 </dependency> 41 <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator --> 42 <dependency> 43 <groupId>org.hibernate</groupId> 44 <artifactId>hibernate-validator</artifactId> 45 <version>6.1.0.Final</version> 46 </dependency> 47 <dependency> 48 <groupId>org.springframework.boot</groupId> 49 <artifactId>spring-boot-starter-thymeleaf</artifactId> 50 </dependency> 51 <!-- aop --> 52 <dependency> 53 <groupId>org.springframework.boot</groupId> 54 <artifactId>spring-boot-starter-aop</artifactId> 55 </dependency> 56 </dependencies> 57 58 <build> 59 <plugins> 60 <plugin> 61 <groupId>org.springframework.boot</groupId> 62 <artifactId>spring-boot-maven-plugin</artifactId> 63 </plugin> 64 </plugins> 65 <resources> 66 <resource> 67 <directory>src/main/resources</directory> 68 <includes> 69 <include>**/*.properties</include> 70 <include>**/*.yml</include> 71 <include>**/*.xml</include> 72 <include>**/*.p12</include> 73 <include>**/*.html</include> 74 <include>**/*.jpg</include> 75 <include>**/*.png</include> 76 </includes> 77 </resource> 78 </resources> 79 </build> 80 81 </project>
搞一个业务层接口,然后搞一个业务层接口实现子类。
1 package com.demo.service; 2 3 public interface UserService { 4 5 public String login(String username, String password); 6 }
1 package com.demo.service.impl; 2 3 import org.springframework.stereotype.Service; 4 5 import com.demo.service.UserService; 6 7 @Service 8 public class UserServiceImpl implements UserService { 9 10 @Override 11 public String login(String username, String password) { 12 if (username.equals("admin") && password.equals("123456")) { 13 return "success!!!"; 14 } 15 return "fail!!!"; 16 } 17 18 }
定义AOP程序类,对业务方法进行拦截,这里使用环绕通知处理。
1 package com.demo.aop; 2 3 import java.util.Arrays; 4 5 import org.aspectj.lang.ProceedingJoinPoint; 6 import org.aspectj.lang.annotation.Around; 7 import org.aspectj.lang.annotation.Aspect; 8 import org.slf4j.Logger; 9 import org.slf4j.LoggerFactory; 10 import org.springframework.stereotype.Component; 11 12 /** 13 * 定义业务层拦截 14 * 15 * @author Aiyufei 16 * 17 */ 18 @Component 19 @Aspect 20 public class ServiceAspect { 21 22 private Logger log = LoggerFactory.getLogger(ServiceAspect.class); 23 24 /** 25 * 环绕通知 26 * 27 * @param point 28 * @return 29 * @throws Throwable 30 */ 31 @Around("execution(* com.demo.service..*.*(..))") 32 public Object arroudInvoke(ProceedingJoinPoint point) throws Throwable { 33 this.log.info("the before 执行参数: " + Arrays.toString(point.getArgs())); 34 Object proceed = point.proceed(point.getArgs()); 35 this.log.info("the after 返回结果:" + proceed); 36 return proceed; 37 } 38 39 }
搞一个控制层类,如下所示:
1 package com.demo.controller; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Controller; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.RequestParam; 7 import org.springframework.web.bind.annotation.ResponseBody; 8 9 import com.demo.service.UserService; 10 11 @Controller 12 public class SpringBootController { 13 14 @Autowired 15 private UserService userService; 16 17 @RequestMapping(value = "/login") 18 @ResponseBody 19 public String hello(@RequestParam(value = "username") String username, 20 @RequestParam(value = "password") String password) { 21 System.out.println("hello world!!!"); 22 String login = userService.login(username, password); 23 return login; 24 } 25 26 }
使用postman测试一下,如下所示:
由于将切入点设置在了所有的业务层上,所以在调用UserService接口方法时会自动执行AOP拦截。