0
点赞
收藏
分享

微信扫一扫

Spring(SpringBoot)--AOP--使用/实例

你的益达233 2022-02-25 阅读 34


简介

说明

        本文介绍Spring的AOP的用法,以及其顺序的控制。

AOP的执行流程图

Spring(SpringBoot)--AOP--使用/实例_spring

创建工程

Spring(SpringBoot)--AOP--使用/实例_spring_02

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo_springaop-simple</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo_springaop-simple</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
</properties>

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

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

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>org.junit.vintage</groupId>-->
<!-- <artifactId>junit-vintage-engine</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

公共代码

启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoSpringaopSimpleApplication {
public static void main(String[] args) {
SpringApplication.run(DemoSpringaopSimpleApplication.class, args);
}
}

Entity

package com.example.demo.entity;

import lombok.Data;

@Data
public class User {
private Integer id;
private String userName;
private String note;
}

Service

package com.example.demo.service;

import com.example.demo.entity.User;

public interface UserService {
public void printUser(User user);
}
package com.example.demo.service.impl;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
@Override
public void printUser(User user) {
if (user == null) {
throw new RuntimeException("检查用户参数是否为空");
}
System.out.print("id = " + user.getId());
System.out.print("\t userName = " + user.getUserName());
System.out.println("\t note = " + user.getNote());
}
}

Controller

package com.example.demo.controller;

import com.example.demo.annotation.OperationLog;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
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.ResponseBody;

@RequestMapping("/user")
@Controller
public class UserController {
@Autowired
UserService userService;

@RequestMapping("/print")
@ResponseBody
public User testPrint(User user) {
userService.printUser(user);
return user;
}

@RequestMapping("/add")
@ResponseBody
@OperationLog(type = "添加", desc = "添加数据")
public User testAdd(User user) {
return user;
}

@RequestMapping("/update")
@ResponseBody
@OperationLog(type = "更新", desc = "更新数据")
public User testUpdate(User user) {
userService.printUser(user);
return user;
}
}

单AOP(单个Aspect正常操作)

代码

package com.example.demo.aspect;

import com.example.demo.annotation.OperationLog;
import com.example.demo.entity.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
//@Order(1)
public class SimpleAspect {
@Pointcut("execution(* com.example.demo.service.impl.UserServiceImpl.printUser(..))")
public void pointCut() {

}

@Before("pointCut()")
public void before() {
System.out.println("SimpleAspect.before");
}

@Around("pointCut()")
public void around1(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("SimpleAspect.around1:" + "around before");
joinPoint.proceed();
System.out.println("SimpleAspect.around1:" + "around after");
}

@After("pointCut()")
public void after() {
System.out.println("SimpleAspect.after");
}

@AfterReturning("pointCut()")
public void afterReturning() {
System.out.println("SimpleAspect.afterReturning");
}

@AfterThrowing("pointCut()")
public void afterThrowing() {
System.out.println("SimpleAspect.afterThrowing");
}
}

测试

postman访问:​​http://localhost:8080/user/print?id=321&userName=Tony&note=abc​​

后端结果

SimpleAspect.around1:around before
SimpleAspect.before
id = 321 userName = Tony note = abc
SimpleAspect.afterReturning
SimpleAspect.after
SimpleAspect.around1:around after

postman结果

{
"id": 321,
"userName": "Tony",
"note": "abc"
}

单AOP(不调用jointPoint.proceed())

代码

package com.example.demo.aspect;

import com.example.demo.annotation.OperationLog;
import com.example.demo.entity.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
//@Order(1)
public class SimpleAspect {
@Pointcut("execution(* com.example.demo.service.impl.UserServiceImpl.printUser(..))")
public void pointCut() {

}

@Before("pointCut()")
public void before() {
System.out.println("SimpleAspect.before");
}

@Around("pointCut()")
public void around2(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("SimpleAspect.around2:"+ "around before");
// joinPoint.proceed();
System.out.println("SimpleAspect.around2:" + "around after");
}

@After("pointCut()")
public void after() {
System.out.println("SimpleAspect.after");
}

@AfterReturning("pointCut()")
public void afterReturning() {
System.out.println("SimpleAspect.afterReturning");
}

@AfterThrowing("pointCut()")
public void afterThrowing() {
System.out.println("SimpleAspect.afterThrowing");
}
}

测试

postman访问:​​http://localhost:8080/user/print?id=321&userName=Tony&note=abc​​

后端结果

SimpleAspect.around2:around before
SimpleAspect.around2:around after

postman结果

SimpleAspect.around2:around before
SimpleAspect.around2:around after

单AOP(只打印joinPoint信息)

代码

package com.example.demo.aspect;

import com.example.demo.annotation.OperationLog;
import com.example.demo.entity.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
//@Order(1)
public class SimpleAspect {
@Pointcut("execution(* com.example.demo.service.impl.UserServiceImpl.printUser(..))")
public void pointCut() {

}

@Before("pointCut()")
public void before() {
System.out.println("SimpleAspect.before");
}

@Around("pointCut()")
public void around3(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
System.out.println("joinPoint.getTarget().toString() : " + joinPoint.getTarget().toString());
System.out.println("methodSignature.getName() : " + methodSignature.getName());
System.out.println("method.getName() : " + method.getName());
System.out.println("method.getReturnType().getName() : " + method.getReturnType().getName());

Object[] objects = joinPoint.getArgs();
for (Object o : objects) {
System.out.println(o);
if (o instanceof User) {
System.out.println("id是:" + ((User)(o)).getId() +
"; 名字是:" + ((User)(o)).getUserName() +
"; 备注是:" + ((User)(o)).getNote());
}
}
}

@After("pointCut()")
public void after() {
System.out.println("SimpleAspect.after");
}

@AfterReturning("pointCut()")
public void afterReturning() {
System.out.println("SimpleAspect.afterReturning");
}

@AfterThrowing("pointCut()")
public void afterThrowing() {
System.out.println("SimpleAspect.afterThrowing");
}
}

测试

postman访问:​​http://localhost:8080/user/print?id=321&userName=Tony&note=abc​​

后端结果

joinPoint.getTarget().toString()  : com.example.demo.service.impl.UserServiceImpl@279268ba
methodSignature.getName() : printUser
method.getName() : printUser
method.getReturnType().getName() : void
User(id=321, userName=Tony, note=abc)
id是:321; 名字是:Tony; 备注是:abc

postman结果

{
"id": 321,
"userName": "Tony",
"note": "abc"
}

两AOP+@Order(都不调用proceed())

代码

package com.example.demo.aspect;

import com.example.demo.annotation.OperationLog;
import com.example.demo.entity.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@Order(1)
public class SimpleAspect {
@Pointcut("execution(* com.example.demo.service.impl.UserServiceImpl.printUser(..))")
public void pointCut() {

}

@Before("pointCut()")
public void before() {
System.out.println("SimpleAspect.before");
}

@Around("pointCut()")
public void around2(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("SimpleAspect.around2:"+ "around before");
// joinPoint.proceed();
System.out.println("SimpleAspect.around2:" + "around after");
}

@After("pointCut()")
public void after() {
System.out.println("SimpleAspect.after");
}

@AfterReturning("pointCut()")
public void afterReturning() {
System.out.println("SimpleAspect.afterReturning");
}

@AfterThrowing("pointCut()")
public void afterThrowing() {
System.out.println("SimpleAspect.afterThrowing");
}
}
package com.example.demo.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@Order(2)
public class OrderTestAspect {
@Pointcut("execution(* com.example.demo.service.impl.UserServiceImpl.printUser(..))")
public void pointCut() {

}

@Before("pointCut()")
public void before() {
System.out.println("OrderTestAspect.before");
}

@Around("pointCut()")
public void around1(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("OrderTestAspect.around1:" + "around before");
// joinPoint.proceed();
System.out.println("OrderTestAspect.around1:" + "around after");
}

@After("pointCut()")
public void after() {
System.out.println("OrderTestAspect.after");
}

@AfterReturning("pointCut()")
public void afterReturning() {
System.out.println("OrderTestAspect.afterReturning");
}

@AfterThrowing("pointCut()")
public void afterThrowing() {
System.out.println("OrderTestAspect.afterThrowing");
}
}

测试

正常顺序

postman访问:​​http://localhost:8080/user/print?id=321&userName=Tony&note=abc​​

后端结果

SimpleAspect.around2:around before
SimpleAspect.around2:around after

前端结果

{
"id": 321,
"userName": "Tony",
"note": "abc"
}

颠倒顺序

postman访问:​​http://localhost:8080/user/print?id=321&userName=Tony&note=abc​​

后端结果

OrderTestAspect.around1:around before
OrderTestAspect.around1:around after

前端结果

{
"id": 321,
"userName": "Tony",
"note": "abc"
}

两AOP+@Order(都调用proceed())

代码

package com.example.demo.aspect;

import com.example.demo.annotation.OperationLog;
import com.example.demo.entity.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@Order(1)
public class SimpleAspect {
@Pointcut("execution(* com.example.demo.service.impl.UserServiceImpl.printUser(..))")
public void pointCut() {

}

@Before("pointCut()")
public void before() {
System.out.println("SimpleAspect.before");
}

@Around("pointCut()")
public void around1(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("SimpleAspect.around1:" + "around before");
joinPoint.proceed();
System.out.println("SimpleAspect.around1:" + "around after");
}

@After("pointCut()")
public void after() {
System.out.println("SimpleAspect.after");
}

@AfterReturning("pointCut()")
public void afterReturning() {
System.out.println("SimpleAspect.afterReturning");
}

@AfterThrowing("pointCut()")
public void afterThrowing() {
System.out.println("SimpleAspect.afterThrowing");
}
}
package com.example.demo.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@Order(2)
public class OrderTestAspect {
@Pointcut("execution(* com.example.demo.service.impl.UserServiceImpl.printUser(..))")
public void pointCut() {

}

@Before("pointCut()")
public void before() {
System.out.println("OrderTestAspect.before");
}

@Around("pointCut()")
public void around2(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("OrderTestAspect.around1:" + "around before");
joinPoint.proceed();
System.out.println("OrderTestAspect.around1:" + "around after");
}

@After("pointCut()")
public void after() {
System.out.println("OrderTestAspect.after");
}

@AfterReturning("pointCut()")
public void afterReturning() {
System.out.println("OrderTestAspect.afterReturning");
}

@AfterThrowing("pointCut()")
public void afterThrowing() {
System.out.println("OrderTestAspect.afterThrowing");
}
}

测试

正常顺序

后端结果

SimpleAspect.around1:around before
SimpleAspect.before
OrderTestAspect.around1:around before
OrderTestAspect.before
id = 321 userName = Tony note = abc
OrderTestAspect.afterReturning
OrderTestAspect.after
OrderTestAspect.around1:around after
SimpleAspect.afterReturning
SimpleAspect.after
SimpleAspect.around1:around after

postman结果

{
"id": 321,
"userName": "Tony",
"note": "abc"
}

颠倒顺序之后

后端结果

OrderTestAspect.around1:around before
OrderTestAspect.before
SimpleAspect.around1:around before
SimpleAspect.before
id = 321 userName = Tony note = abc
SimpleAspect.afterReturning
SimpleAspect.after
SimpleAspect.around1:around after
OrderTestAspect.afterReturning
OrderTestAspect.after
OrderTestAspect.around1:around after

postman结果:

{
"id": 321,
"userName": "Tony",
"note": "abc"
}

两AOP+@Order(高优先级调用proceed())

代码

package com.example.demo.aspect;

import com.example.demo.annotation.OperationLog;
import com.example.demo.entity.User;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@Order(1)
public class SimpleAspect {
@Pointcut("execution(* com.example.demo.service.impl.UserServiceImpl.printUser(..))")
public void pointCut() {

}

@Before("pointCut()")
public void before() {
System.out.println("SimpleAspect.before");
}

@Around("pointCut()")
public void around1(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("SimpleAspect.around1:" + "around before");
joinPoint.proceed();
System.out.println("SimpleAspect.around1:" + "around after");
}

@After("pointCut()")
public void after() {
System.out.println("SimpleAspect.after");
}

@AfterReturning("pointCut()")
public void afterReturning() {
System.out.println("SimpleAspect.afterReturning");
}

@AfterThrowing("pointCut()")
public void afterThrowing() {
System.out.println("SimpleAspect.afterThrowing");
}
}
package com.example.demo.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@Order(2)
public class OrderTestAspect {
@Pointcut("execution(* com.example.demo.service.impl.UserServiceImpl.printUser(..))")
public void pointCut() {

}

@Before("pointCut()")
public void before() {
System.out.println("OrderTestAspect.before");
}

@Around("pointCut()")
public void around1(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("OrderTestAspect.around1:" + "around before");
// joinPoint.proceed();
System.out.println("OrderTestAspect.around1:" + "around after");
}

@After("pointCut()")
public void after() {
System.out.println("OrderTestAspect.after");
}

@AfterReturning("pointCut()")
public void afterReturning() {
System.out.println("OrderTestAspect.afterReturning");
}

@AfterThrowing("pointCut()")
public void afterThrowing() {
System.out.println("OrderTestAspect.afterThrowing");
}
}

测试

正常顺序

postman访问:​​http://localhost:8080/user/print?id=321&userName=Tony&note=abc​​

后端结果

SimpleAspect.around1:around before
SimpleAspect.before
OrderTestAspect.around1:around before
OrderTestAspect.around1:around after
SimpleAspect.afterReturning
SimpleAspect.after
SimpleAspect.around1:around after

postman结果

{
"id": 321,
"userName": "Tony",
"note": "abc"
}

颠倒顺序(低优先级调用proceed())

postman访问:​​http://localhost:8080/user/print?id=321&userName=Tony&note=abc​​

后端结果

OrderTestAspect.around1:around before
OrderTestAspect.around1:around after

postman结果

{
"id": 321,
"userName": "Tony",
"note": "abc"
}

其他网址

《深入浅出Spring Boot 2.x》=> 4.3 AOP开发详解


举报

相关推荐

0 条评论