preface
This article mainly introduces the SpringBoot aspect Aop demo simple explanation.
SpringBoot Aop
Note: If you want to get the project directly, you can jump to the bottom and download the project code through the link.
Section (Aop)
A concept,
AOP (Aspect OrientedProgramming) : Aspect OrientedProgramming (also known as aspect-oriented programming) is a hot topic in software development and an important content in Spring framework. Using AOP, each part of the business logic can be isolated, thus reducing the degree of coupling between each part of the business logic, improving the reusability of the program, and improving the efficiency of development.
Second, the purpose
Logging, performance statistics, security control, permission management, transaction processing, exception handling, resource pool management.
Three, break down
1. Aspect: The official abstraction is defined as “modularity of a concern that may crosscut multiple objects.” In this case, “aspect” is the specific behavior that class TestAspect cares about. For example, the call to aserviceimp.bara () is one of the behaviors that TestAspect cares about. Aop: Aspect is configured in the ApplicationContext.
2. Joinpoint: an action during program execution, for example, a call to aserviceImp.bara () or an exception thrown by bServiceImp.barb (String _msg, int _type).
Advice: The action of the aspect for a join point, for example, the action in TestAspect to log methods of all classes in the com.spring.service package, is an Advice. Where a “slice” can contain more than one “Advice,” such as TestAspect. There are five types of Advice:
- A Before advice: Before advice is executed Before A JoinPoint, but this advice does not prevent execution Before the JoinPoint. XML uses the AOP :before element in aop:aspect to declare; For example, the doBefore method in TestAspect. Use @before declarations in annotations; For example, the doBefore method in the Testanannotation aspect.
- B After advice: Advice that is performed when a join point exits (whether it is a normal return or an abnormal exit). XML uses the AOP: After element in AOP :aspect. For example, the doAfter method in TestAspect, so the call to bServiceImp.barb in AOPTest throws an exception, the doAfter method is still executed. Use the @after declaration in annotations.
- C After return advice: Advice executed After a join point completes normally, excluding exceptions thrown. Aop :aspect is declared using elements in XML. Use the @afterreturning declaration in annotations;
- D Around advice: Advice that surrounds a connection point, similar to the doFilter method of Filter in the Servlet specification on the Web. Custom behavior can be completed before and after a method is called, or you can choose not to. Declarations in XML use aop:around elements in AOP :aspect. For example, the doAround method in TestAspect. Use the @around declaration in annotations.
- E After Throwing advice: An advice that is executed when a method throws an exception and exits. Aop: after-Throwing element is used to declare aop:aspect in XML. For example, the doThrowing method in TestAspect. An @afterThrowing declaration is used in annotations.
- Order of notification execution: pre-notification → before wrapping the notification join point → join point execution → after wrapping the notification join point → return notification → post notification →(if an exception occurs) exception notification → post notification.
Pointcut matches the assertions of join points, and in AOP advice is associated with a Pointcut expression. For example, all of the join points that are the focus of advice in TestAspect are executed by the pointcut expression execution(* com.spring.service.. (..) ).
Note: Reference for the above theoretical knowledge:www.cnblogs.com/yepei/p/473…
The development of preparation
Environmental requirements
The JDK: 1.8
SpringBoot: 2.2.6. RELEASE
Maven’s dependency on spring-boot-starter-AOP is the same as that of a normal Springboot project.
The pom.xml file is as follows:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> < project. Reporting. OutputEncoding > utf-8 < / project. Reporting. OutputEncoding > < Java version > 1.8 < / Java version > Piler < maven.com. Source > 1.8 < / maven.com piler. Source > < maven.com piler. Target > 1.8 < / maven.com piler. Target > < / properties > <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath/> </parent> <dependencies> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.68</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <scope>test</scope> </dependency> </dependencies>Copy the code
Application. Properties file configuration:
banner.charset=UTF-8
server.tomcat.uri-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
spring.messages.encoding=UTF-8
spring.application.name=springboot-aspect
server.port=8180
Copy the code
The code
When SpringBoot uses aspects, all it needs to do is declare a custom Aspect class with the @aspect annotation, and then add the corresponding annotation to the custom Aspect class method. For example, here we want to do a request response encryption and decryption aspect processing, the business layer only needs to care about the code logic implementation, but does not need to care about the request parameters and response parameters encryption and decryption implementation. So first we need to define a custom encryption and decryption Aspect class, add the @aspect annotation to this class, and then define a common Pointcut that points to the package to be processed. Then define a pre-notification (add @before annotation) and a post-notification (add @afterRETURNING) method to implement it.
Here we set the pointcut to control all requests in the package.
Pointcut code examples:
@Pointcut("execution(public * com.pancm.web.*.*(..) )")
public void doOperation() {}Copy the code
Then define a pre-notification to decrypt the data of the request parameter. Here we use the name of the entity class User to decrypt the data. The actual use can be written according to their own situation.
Examples of pre-notification code:
@Before("doOperation()")
public void before(JoinPoint joinPoint) throws Throwable{
Object[] objs = joinPoint.getArgs();
for (Object obj : objs) {
User user =(User) obj;
System.out.println("Pre-notification accepted parameters :"+user); String name =base64DeStr(user.getName()); user.setName(name); }}Copy the code
After writing the method of pre-notification, we are writing the code of post-notification, which is basically the same as pre-notification, that is, the returned data is encrypted.
Examples of post-notification code:
@AfterReturning(returning = "object", pointcut = "doOperation()")
public void doAfterReturning(Object object) {
ResultBody resultBody = (ResultBody) object;
String str =null;
try {
str=base64EnStr(resultBody.getResult());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
resultBody.setResult(str);
System.out.println("Parameters for post-notification response :"+resultBody);
}
Copy the code
Examples of complete code:
@Aspect
@Component
public class ParamAspect {
@Pointcut("execution(public * com.pancm.web.*.*(..) )")
public void doOperation() {
}
@Before("doOperation()")
public void before(JoinPoint joinPoint) throws Throwable{
Object[] objs = joinPoint.getArgs();
for (Object obj : objs) {
User user =(User) obj;
System.out.println("Pre-notification accepted parameters :"+user);
String name =base64DeStr(user.getName());
user.setName(name);
}
}
@AfterReturning(returning = "object", pointcut = "doOperation()")
public void doAfterReturning(Object object) {
ResultBody resultBody = (ResultBody) object;
String str =null;
try {
str=base64EnStr(resultBody.getResult());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
resultBody.setResult(str);
System.out.println("Parameters for pre-notification response :"+resultBody);
}
public String base64EnStr(String str) throws UnsupportedEncodingException {
return Base64.getEncoder().encodeToString(str.getBytes("UTF-8"));
}
public static String base64DeStr(String encodeStr) throws UnsupportedEncodingException {
byte[] decodeStr = Base64.getDecoder().decode(encodeStr);
return new String(decodeStr, "UTF-8");
}
Copy the code
Entity class code
public class User { private Long id; private String name; private Integer age; // getters and setters omitted}Copy the code
The code of control layer Z is the same as that of ordinary ones. We only need to do simple processing here. In order to facilitate understanding, the code of service layer and DAO is not written here. :
** Control layer code **
@RestController
@RequestMapping(value = "/api")
public class UserRestController {
@GetMapping("/user")
public ResultBody findByUser(User user) {
System.out.println("User query interface request parameters :"+user);
ResultBody resultBody = new ResultBody();
List<User> userList =new ArrayList<>();
User user2=new User();
user2.setId(1L);
user2.setName("xuwujing");
user2.setAge(18);
userList.add(user2);
resultBody.setCode("0");
resultBody.setResult(userList.toString());
System.out.println("User query interface response parameters :"+resultBody);
returnresultBody; }}Copy the code
App entrance
And the ordinary SpringBoot project is basically the same!
The code is as follows:
@SpringBootApplication
public class AspectApp
{
public static void main( String[] args )
{
SpringApplication.run(AspectApp.class, args);
System.out.println("Aspect started successfully!"); }}Copy the code
A functional test
After writing the code, we start the program. Since it is a Get request, we can test it either in the browser or using Postman to enter the address. Note that we need to base64 the value of name.
Input:
http://localhost:8180/api/user?name=eHV3dWppbmc=
Console printing:
Parameters accepted in the pre-notification :{“name”:”eHV3dWppbmc=”} Parameter used in the user interface query :{“name”:”xuwujing”} User query interface response parameters: {” code “:” 0 “, “result” : “[{18,” age “:” id “: 1,” name “:” xuwujing} “] “} After notification response parameters: {” code “:” 0 “, “result” : “W3siYWdlIjoxOCwiaWQiOjEsIm5hbWUiOiJ4dXd1amluZyJ9XQ = =”}
Request response parameters:
{ “code”: “0”, “message”: null, “result”: “W3siYWdlIjoxOCwiaWQiOjEsIm5hbWUiOiJ4dXd1amluZyJ9XQ==” }
Figure:
other
On the SpringBoot plane Aop demo simple explanation of the article on the explanation here, if there is something wrong, welcome to point out!
The project address
SpringBoot aop project address: github.com/xuwujing/sp…
SpringBoot entire collection address: github.com/xuwujing/sp…
SpringBoot integration series of articles
-
SpringBoot configuration file reading and use of filters and interceptors
-
SpringBoot Restful service
-
SpringBoot+Mybatis+ Druid+PageHelper implements multiple data sources and paging
-
SpringBoot is compatible with ElasticSearch
-
SpringBoot integrates Kafka with Storm
-
SpringBoot integrates Jsp with Thymeleaf
-
SpringBoot integrates Netty and uses Protobuf for data transfer
-
SpringBoot is simply packaged and deployed
-
SpringBoot integration Redis uses Restful style to implement CRUD functionality
-
SpringBoot elegant global exception handling
-
The SpringBoot project implements file uploading and email sending
-
SpringBoot integrates Swagger and Actuator
-
SpringBoot Transaction tutorial
Music to recommend
Pian if jing Hong, wan if you dragon, rong Yao Qiu Ju, Huamao Spring pine. As if xi if light clouds cover the moon, floating xi if the wind back snow. Far and hope of, jiao if the sun rises zhaoxia; And when compelled, there are clearly waves of green. — Comments on netease Cloud
Original is not easy, if you feel good, I hope to give a recommendation! Your support is the biggest motivation for my writing! Copyright: www.cnblogs.com/xuwujing CSDN blog.csdn.net/qazwsxpcm Personal blog: www.panchengming.com