基于JAVA配置的springAOP
一、环境
1、创建maven项目
2、在 pom.xml 添加依赖l:
<?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>com.gyy</groupId>
<artifactId>com.gyy</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--AOP 切面编程 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- 用于测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13-beta-3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
二、创建 —— 业务类、切面类、主配置类、测试类
1、业务类——MathCalculator.java
随便写个简单的业务,如下:
package service;
/**
* @author GYY
* @date 2019/11/29 20:36
*/
public class MathCalculator {
public int div(int i ,int j){
System.out.println("进入业务。。。。。");
return i/j;
}
}
2、切面类——MyAopConfig.java
注意:
- 1)记得在类上加上@Aspect注解,这样才能被识别为切面类
- 2)@Pointcut:用来写切点表达式
- 3)@Before:前置通知
- 4)@After:后置通知
- 5)@AfterReturning:最终通知
- 6)@AfterThrowing:异常抛出通知
package config;
import org.aspectj.lang.annotation.*;
/**
* @author gyy
*/
@Aspect
public class MyAopConfig {
//切点表达式
@Pointcut("execution(public int service.MathCalculator.*(..))")
public void pointCut(){}
@Before("pointCut()")
public void before(){
System.out.println("@Before。。。。。");
}
@After("pointCut()")
public void after(){
System.out.println("@After....");
}
@AfterReturning("pointCut()")
public void methodReturn(){
System.out.println("@AfterReturning.....");
}
@AfterThrowing("pointCut()")
public void methodException(){
System.out.println("@AfterThrowing.....");
}
}
3、主配置类——MainConfig.java
注意:
- 1)记得在类上加入@Configuration注解,这样才能被识别为配置类
- 2)@EnableAspectJAutoProxy表示开启AOP代理,必写
package config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import service.MathCalculator;
/**
* @author GYY
* @date 2019/11/29 21:18
*/
@Configuration
@EnableAspectJAutoProxy
public class MainConfig {
@Bean
public MathCalculator mathCalculator(){
return new MathCalculator();
}
@Bean
public MyAopConfig myAopConfig(){
return new MyAopConfig();
}
}
4、编写测试类
注意:
- 这里的MathCalculator要通过getBean()来获取,如果直接通过 new MathCalculator,是无效的
package test;
import config.MainConfig;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import service.MathCalculator;
/**
* @author GYY
* @date 2019/11/29 20:37
*/
public class Test_AOP {
@Test
public void test1(){
//创建上下文,读取配置类
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
//获取bean
MathCalculator math = applicationContext.getBean(MathCalculator.class);
//调用方法
math.div(2,1);
}
}
5、测试
测试结果:
三、优化
如果想让通知输出方法的名字和入参该怎么做呢?
修改MyAopConfig.java
注意:
- 使用JoinPoint作为方法参数时,必须放在参数的第一位,否则报错
package config;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import java.util.Arrays;
/**
* @author gyy
*/
@Aspect
public class MyAopConfig {
@Pointcut("execution(public int service.MathCalculator.*(..))")
public void pointCut(){}
@Before(value = "pointCut()")
public void before(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
System.out.println(joinPoint.getSignature().getName()+" 运行中 @Before方法入参为:{"+ Arrays.asList(args) + "}");
}
@After("pointCut()")
public void after(JoinPoint joinPoint){
System.out.println(joinPoint.getSignature().getName()+" 运行后 @After");
}
@AfterReturning(value = "pointCut()",returning = "result")
public void methodReturn(Object result){
System.out.println("@AfterReturning.....运行结果{"+result+"}");
}
@AfterThrowing(value = "pointCut()",throwing = "e")
public void methodException(JoinPoint joinPoint,Exception e){
System.out.println(joinPoint.getSignature().getName()+" @AfterThrowing.....异常信息{"+e+"}");
}
}
测试: