Java是面向对象编程,Java AOP是面向切面编程,最近学习该部分内容知识,讲学习心得在这里做一个整理,以帮助后续学习以及使用。
首先什么事AOP?个人理解,在开发过程中,又核心业务,也有非核心业务。例如一个登陆功能,在登录功能中核心业务是进行登陆操作,继判断用户是否在数据库中存在;同事也有一些非核心业务,如日志记录,参数校验等。模块化开发思想,将这三部分模块进行分开处理,从而不会使得代码冗余,方便维护。但是模块分开之后,我所需要的效果还是要包含校验,日志和登录。AOP所处理的,就是将这三部分内容按照一定的规则组合起来。如下图:
AOP的底层核心,就是Java的动态代理机制,AOP中有几个很重要的概念,整理如下表:
横切关注点 | 从每个方法中抽取出来的同一类非核心业务 |
切面(Aspect) | 横切关注点的分装类,每个关注点体现为一个通知 |
通知Advice | 具体的方法 |
目标 | 目标对象 |
代理 | 向目标对象应用通知之后创建的代理对象 |
连接点JoinPoint | 横切关注点在程序代码中的具体体现,对应程序执行的某个特定位置,例如:类某个方法调用前、调用后、方法捕获到异常后等。 |
Spring为开发者提供了自己的一套AOP框架。但实际开发过程中,使用最多的还是AspectJ框架,该框架是目前最为流行的AOP框架,在Spring2.0开始,支持注解和XML配置文件两种方式进行配置使用。
AspectJ提供了5种类型的通知注解,常用的如下表:
@Before | 前置通知,在方法执行前执行 |
@After | 后置通知,在方法执行后执行 |
@AfterRunning | 返回通知,在方法返回结果后返回,可以利用returning属性,接收方法的返回结果 |
@AfterThrowing | 异常通知 |
其中每一个注解,都需要指定一个execution,继改切面作用在哪一个方法之中,样例如下:
@Before(value = "execution(* com.springboot.aspectj.springboot_aspect.service.*.*(..))")
其中execution表达式中每一个字符解释如下图:
下面以SpringBoot,结合Aspect做一个示例。首先简单的业务需求,有一个add方法,有两个int类型的参数相加,返回结果。
1、首先pom引入AOP的maven依赖
org.springframework.boot
spring-boot-starter-aop
2、编写切面类
/**
* 切面
*/
@Configuration
@Aspect
public class MyAspectJ {
/**
* @Before 前置通知
* @param joinPoint
*/
@Before(value = "execution(* com.springboot.aspectj.springboot_aspect.service.*.*(..))")
public void before(JoinPoint joinPoint){
String MethodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("before MethodName:"+MethodName+",argNames:"+ Arrays.toString(args));
}
/**
* @After后置通知
* @param joinPoint
*/
@After(value = "execution(* com.springboot.aspectj.springboot_aspect.service.*.*(..))")
public void after( JoinPoint joinPoint){
String MethodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("after MethodName:"+MethodName+",argNames:"+ Arrays.toString(args));
}
/**
* @AfterReturning返回通知
* @param joinPoint
* @param result
*/
@AfterReturning(value = "execution(* com.springboot.aspectj.springboot_aspect.service.*.*(..))",returning = "result")
public void result(JoinPoint joinPoint,Object result){
String MethodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("AfterReturning MethodName:"+MethodName+",argNames:"+ Arrays.toString(args)+",result:" + result);
}
}
3、编写一个目标类,实现具体的核心业务:
public interface CalcService {
public int add(int a,int b);
}
@Service
public class CalcServiceImpl implements CalcService {
@Override
public int add(int a, int b) {
int result = a + b;
System.out.println("a:"+a+",b:"+b+",result:"+result);
return result;
}
}
4、编写测试类,查看运行结果
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAspectApplicationTests {
@Autowired
private CalcService calcService;
@Test
public void contextLoads() {
calcService.add(1,2);
}
}
//结果
before MethodName:add,argNames:[1, 2]
a:1,b:2,result:3
after MethodName:add,argNames:[1, 2]
AfterReturning MethodName:add,argNames:[1, 2],result:3
以上就是自己的一些整理心得,如有不对之处,还请大家指出,谢谢