一、正常编写项目代码
1.编写接口
package com.suchuanlin.service;
public interface Calculator {
int add(int i, int j);
int sub(int i, int j);
int mul(int i, int j);
int div(int i, int j);
}
2.编写实现类,实现接口
package com.suchuanlin.service.impl;
import com.suchuanlin.service.Calculator;
import org.springframework.stereotype.Component;
@Component
public class CalculatorImpl implements Calculator {
@Override
public int add(int i, int j) {
int result = i + j;
return result;
}
@Override
public int sub(int i, int j) {
int result = i - j;
return result;
}
@Override
public int mul(int i, int j) {
int result = i * j;
return result;
}
@Override
public int div(int i, int j) {
int result = i / j;
return result;
}
}
3.编写配置文件
package com.suchuanlin.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration //定义当前为配置类
@ComponentScan(value = "com.suchuanlin") //定义注解包扫描范围
@EnableAspectJAutoProxy //开启aspectj的注解
public class AppConfig {
}
二、配置AOP
4.提取切点,统一管理
package com.suchuanlin.pointcut;
import org.aspectj.lang.annotation.Pointcut;
public class PointCutManager {
@Pointcut("execution(* com.suchuanlin.service.impl.*.*(..))")
public void servicePointCut(){}
}
5.1编写切面类(@Before,@After,@AfterReturning,@AfterThrowing)
package com.suchuanlin.advice;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.junit.jupiter.api.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Modifier;
@Component
@Aspect
@Order(10)
public class LogAdvice {
@Before("com.suchuanlin.pointcut.PointCutManager.servicePointCut()")
public void before(JoinPoint joinPoint){
//1.获取方法所属的类的信息
String simpleName = joinPoint.getTarget().getClass().getSimpleName();
System.out.println("包信息:" + simpleName);
//2.获取方法的修饰符
int modifiers = joinPoint.getSignature().getModifiers();
String string = Modifier.toString(modifiers);
System.out.println("修饰符:" +string);
//3.获取方法名
String name = joinPoint.getSignature().getName();
System.out.println("方法名:" + name);
//4.获取参数列表
Object[] args = joinPoint.getArgs();
System.out.println("参数列表" + args);
System.out.println("beginAdvice:核心代码执行前...");
}
@After("com.suchuanlin.pointcut.PointCutManager.servicePointCut()")
public void after(){
System.out.println("afterAdvice:核心代码执行后...");
}
@AfterReturning("com.suchuanlin.pointcut.PointCutManager.servicePointCut()")
public void afterReturning(){
System.out.println("afterReturningAdvice:核心代码返回值后...");
}
@AfterThrowing("com.suchuanlin.pointcut.PointCutManager.servicePointCut()")
public void afterThrowing(){
System.out.println("afterThrowingAdvice:核心代码抛出异常后...");
}
}
5.2编写切面类(@Around)
package com.suchuanlin.advice;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.junit.jupiter.api.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Order(0)
public class AroundAdvice {
@Around("com.suchuanlin.pointcut.PointCutManager.servicePointCut()")
public Object aroundAdvice(ProceedingJoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
Object result;
try {
//目标盘方法前执行
System.out.println("aroundAdvice:目标方法前执行...");
//调用目标方法
result = joinPoint.proceed(args);
System.out.println("aroundAdvice:目标方法返回后执行...");
} catch (Throwable e) {
System.out.println("aroundAdvice:目标方法抛异常时执行...");
throw new RuntimeException(e);
}
finally {
System.out.println("aroundAdvice:目标方法执行后执行...");
}
return result;
}
}
三、测试
6.编写测试类
package com.suchuanlin.test;
import com.suchuanlin.config.AppConfig;
import com.suchuanlin.service.Calculator;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@SpringJUnitConfig(value = AppConfig.class) //指定配置类
//@SpringJUnitConfig(locations = "classpath:spring-config.xml") //指定配置文件路径
public class SpringAopTest {
@Autowired
private Calculator calculator;
@Test
public void test(){
int add = calculator.add(1, 1);
System.out.println("add = " + add);
}
}
7.输出结果(注意:即使不设置@Order(0),@Around优先级最高,先进后出)
D:\Programs\Java\jdk-17\bin\java.exe...
aroundAdvice:目标方法前执行...
包信息:CalculatorImpl
修饰符:public abstract
方法名:add
参数列表[Ljava.lang.Object;@7b64240d
beginAdvice:核心代码执行前...
afterReturningAdvice:核心代码返回值后...
afterAdvice:核心代码执行后...
aroundAdvice:目标方法返回后执行...
aroundAdvice:目标方法执行后执行...
add = 2
Process finished with exit code 0