1.项目结构:
1.1 基于Aspect的AOP
1.1.1 父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 http://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.9.RELEASE</version>
</parent>
<groupId>com.lance.demo</groupId>
<artifactId>com-lance-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
</project>
1.1.2 module的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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>com-lance-demo</artifactId>
<groupId>com.lance.demo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>com-lance-demo-provider</artifactId>
<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>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1.1.3 主类:
package com.lance.demo.main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan("com.lance.demo")
@SpringBootApplication
public class SpringBootDemoMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoMain.class, args);
}
}
1.1.4 MyService.java
package com.lance.demo.service;
import com.lance.demo.exception.MyException;
import org.springframework.stereotype.Service;
@Service
public class MyService {
public int myFunction() {
System.out.println("MyFunction execute");
return 0;
}
public int myBizFunction() throws MyException {
System.out.println("myBizFunction execute");
return 1;
}
}
1.1.5 MyAspject.java
package com.lance.demo.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class MyAspect {
@Pointcut("execution(public * com.lance.demo.service.*.*(..))")
public void aspect() {
System.out.println("aspect");
}
@Before("aspect()")
public void doBefore(JoinPoint joinPoint) {
System.out.println("doBefore:"+ joinPoint.getArgs() +"," + joinPoint.getSignature());
}
@After("aspect()")
public void doAfter(JoinPoint joinPoint) {
System.out.println("doAfter:"+ joinPoint.getArgs() +"," + joinPoint.getSignature());
}
@AfterReturning("aspect()")
public void doAfterReturning(JoinPoint joinPoint) {
System.out.println("doAfterReturning:" + joinPoint.getArgs() +"," + joinPoint.getSignature());
}
@AfterThrowing(pointcut = "aspect()",throwing = "e")
public void deAfterThrowing(JoinPoint joinPoint,Throwable e) {
if(e == null) {
System.out.println("deAfterThrowing");
} else {
System.out.println("deAfterThrowing:" + e);
}
}
@Around("aspect()")
public Object deAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("deAround before");
Object object = joinPoint.proceed();
System.out.println("deAround after");
return object;
}
}
1.1.6单元测试类MyServiceTest
package com.lance.demo.service;
import com.lance.demo.main.SpringBootDemoMain;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SpringBootDemoMain.class)
@WebAppConfiguration
public class MyServiceTest {
@Autowired
private MyService myService;
@Test
public void myFunction(){
myService.myFunction();
}
@Test
public void myBizFunction(){
int result = myService.myBizFunction();
System.out.println("result:" + result);
}
}
1.1.7 输出结果:
deAround before
doBefore:[Ljava.lang.Object;@444cc791,int com.lance.demo.service.MyService.myBizFunction()
myBizFunction execute
doAfterReturning:[Ljava.lang.Object;@444cc791,int com.lance.demo.service.MyService.myBizFunction()
doAfter:[Ljava.lang.Object;@444cc791,int com.lance.demo.service.MyService.myBizFunction()
deAround after
result:1
1.2 ControllerAdvice仅对controller层有效的AOP
1.2.1 MyController.java
package com.lance.demo.controller;
import com.lance.demo.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@Autowired
private MyService myService;
@RequestMapping("/hello")
public String hello() {
int result = myService.myFunction();
return "Hello World!" + result;
}
@RequestMapping("/biz/hello")
public String bizHello() {
int result = myService.myBizFunction();
return "Hello World!" + result;
}
}
1.2.2 GlobalExceptionHandler.java
package com.lance.demo.exception;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public Object exceptionHandler(Exception e) {
log.error("exceptionHandler error.",e);
return "Exception";
}
@ExceptionHandler(MyException.class)
@ResponseBody
public Object myExceptionHandler(Exception e) {
log.error("myExceptionHandler error.",e);
return "MyException";
}
}
1.2.3 自定义异常类MyException.java
package com.lance.demo.exception;
public class MyException extends RuntimeException {
public MyException(String message) {
super(message);
}
}