在idea新建maven工程
pom文件如下:
<?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>
<groupId>org.example</groupId>
<artifactId>aopTest</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
刷新maven依赖
新建这几个类:
package com.zzj;
public class MyBusiness {
public int doBusiness(int i, int j) {
System.out.println("MyBusiness >> doBusiness");
return i / j;
}
}
package com.zzj;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import java.util.Arrays;
@Aspect
public class MyAspects {
//抽取公共的切入点表达式
//1、本类引用
//2、其他的切面引用
@Pointcut("execution(public int com.zzj.MyBusiness.*(..))")
private void pointCut() {
System.out.println("pointCut()");
}
@Before(value="pointCut()")
public void start(JoinPoint joinPoint) {
System.out.println("Before>>>>"+joinPoint.getSignature().getName()+">>>>"+ Arrays.toString(joinPoint.getArgs()));
}
@After(value ="pointCut()")
public void logEnd(JoinPoint joinpoint) {
System.out.println("After>>>>>"+joinpoint.getSignature().getName()+">>>>"+Arrays.toString(joinpoint.getArgs()));
}
@AfterReturning(value ="execution(public int com.zzj.MyBusiness.*(..))",returning="object")
public void logReturn(Object object) {
System.out.println("AfterReturning>>>>"+object);
}
@Around(value="pointCut()")
public Object logAround(ProceedingJoinPoint joinpoint) throws Throwable {
System.out.println("Around>>begin>>"+joinpoint.getSignature().getName()+">>>>"+Arrays.toString(joinpoint.getArgs()));
Object retVal = joinpoint.proceed();
System.out.println("Around>>end>>"+joinpoint.getSignature().getName()+">>>>"+Arrays.toString(joinpoint.getArgs()));
return retVal;
}
@AfterThrowing(value = "execution(public int com.zzj.MyBusiness.*(..))",throwing = "object")
public void logException(Exception object) {
System.out.println("AfterThrowing>>>>"+object);
}
}
package com.zzj;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@EnableAspectJAutoProxy
@Configuration
public class MyConfig {
//业务逻辑类加入到容器中
@Bean
public MyBusiness mathCalculator() {
System.out.println("MyBusiness bean");
return new MyBusiness();
}
//切面类加入到容器中
@Bean
public MyAspects logAspects() {
System.out.println("MyAspects bean");
return new MyAspects();
}
}
package com.zzj;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestAOP {
@Test
public void test() {
AnnotationConfigApplicationContext aac = new AnnotationConfigApplicationContext(MyConfig.class);
MyBusiness mc = aac.getBean(MyBusiness.class);
mc.doBusiness(1, 2);
aac.close();
}
}
运行结果:
MyBusiness bean
MyAspects bean
Around>>begin>>doBusiness>>>>[1, 2]
Before>>>>doBusiness>>>>[1, 2]
MyBusiness >> doBusiness
Around>>end>>doBusiness>>>>[1, 2]
After>>>>>doBusiness>>>>[1, 2]
AfterReturning>>>>0
结论:
1 IOC容器启动,加载配置类MyConfig,将业务类MyBusiness的对象和切面类MyAspects的对象注入到容器
2 调用业务方法时:容器会先调用@Around标注的方法的前一部分(joinpoint.proceed()之前的部分),
3 再调用@Before标注的方法,
4 再调用业务方法,即MyBusiness的doBusiness方法
5 再调用@Around标注的方法的后一部分(joinpoint.proceed()之后的部分)
6 再调用@After标注的方法
7 再调用@AfterReturning标注的方法