springboot中面向切面编程
AOP面向切面编程
AOP:spring中提出AOP概念,就是通过动态地为项目中某些类在运行过程中创建代理对象,在代理对象中完成附加功能 | 额外功能;保证在处理业务时能够更加专注于自己的业务逻辑开发。
概念:
- 1)通知(Advice):除了目标方法以外的操作称之为通知,包括日志通知,性能通知,事务通知等;
- 2)切入点(pointcut):用来告诉项目中哪些类中哪些方法在执行过程中加入通知;
- 3)切面(Aspect):通知 + 切入点
Spring中的AOP编程,步骤
- 开发通知,前置,后置,环绕,异常
- 配置通知 并 组装切面
<bean id class="xxxAdvice"> <aop:config> <aop:pointcut expression="exection | within | annotation | args "> <aop:advisor advice-ref=" " pointcut-ref=" "> </aop:config>
SpringBoot中的切面编程
需要先引入spring-boot-starter-aop
相关注解:@Aspect :修饰范围作用在类上, 代表这个类是一个切面配置类。相当于<aop:config>
通知相关注解:
@Before:前置通知,修饰范围:用在方法上,或者类上;Value属性:用在哪个方法上
@After:后置通知,修饰范围:用在方法上,或者类上;Value属性:用在哪个方法上
@Around:环绕通知,修饰范围:用在方法上,或者类上;Value属性:用在哪个方法上
@Order:顺序控制,修饰范围:用在方法上,或者类上,在springboot中只能作用在类上; Value属性:int,int值越小,迁址通知的执行顺序越靠前,后置通知则相反,因为多个aop切面同样是一个“栈式”的结构,先进后出。
修饰范围:用在方法上,或者类上;Value属性:用在哪个方法上
@Before和@After实例:
@Component
@Aspect
public class MyAspect {
@Before(value="within(com.test.service.*ServiceImpl)")
public void before(){
System.out.println("============前置通知=============");
}
}
如果在@Before和@After中想要获取运行时方法的相关信息,在自定义通知方法中加入JointPoint参数:
// @After(value = "within(com.test.service.*ServiceImpl)")
// public void after(JoinPoint joinPoint){
// System.out.println("============后置通知=============");
// System.out.println("当前执行方法名: "+joinPoint.getSignature().getName());
// System.out.println("当前执行方法参数: "+joinPoint.getArgs());
// System.out.println("当前目标对象: "+joinPoint.getTarget());
// }
@Around:执行目标方法之前会进入环绕通知,环绕通知放行之后,才会执行目标方法,执行目标方法之后,再回到环绕通知。
(注意这里要定义成Object类型的方法,因为如果执行方法有结果返回的话,需要通过环绕通知的Object返回结果。)
@Around(value = "within(com.wuhaotian.service.*ServiceImpl)")
public Object around(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("=============在方法执行前进入环绕通知=============");
System.out.println("当前执行方法名: "+proceedingJoinPoint.getSignature().getName());
System.out.println("当前执行方法参数: "+proceedingJoinPoint.getArgs());
System.out.println("当前目标对象: "+proceedingJoinPoint.getTarget());
//放行执行目标方法
try {
Object proceed = proceedingJoinPoint.proceed();
System.out.println("=============在方法执行后进入环绕通知=============");
return proceed;
} catch (Throwable throwable) {
System.out.println("异常处理");
return null;
}
}