Spring-AOP注解开发

Posted lvbl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring-AOP注解开发相关的知识,希望对你有一定的参考价值。

微信公众号:Java修炼手册
关注可获取3T免费学习资料,助你从0到1;

**AOP注解开发**
***AOP代码实现(执行计算前后输入输出目标代码)***
1 定义一个业务逻辑类(MathCalculator);在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常)

1 public class MathCalculator {
2 public int div(int i,int j){
3 System.out.println("MathCalculator...div...");
4 return i/j; 
5 }
6}

 

```
2 定义一个日志切面类(LogAspects):切面类里面的方法需要动态感知MathCalculator.div运行到哪里然后执行;

1@Aspect
2public class LogAspects {
3
4 //抽取公共的切入点表达式
5 //1、本类引用
6 //2、其他的切面引用
7 @Pointcut("execution(public int com.atguigu.aop.MathCalculator.*(..))")
8 public void pointCut(){};
9
10 //@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入)
11 //1使用引入切点方法
12 //joinPoint:用获取方法信息
13 @Before("pointCut()")
14 public void logStart(JoinPoint joinPoint){
15 Object[] args = joinPoint.getArgs();
16 System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+Arrays.asList(args)+"}");
17 }
18 //2使用引用外部切点类的方法
19 @After("com.atguigu.aop.LogAspects.pointCut()")
20 public void logEnd(JoinPoint joinPoint){
21 System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
22 }
23
24 //JoinPoint一定要出现在参数表的第一位
25 @AfterReturning(value="pointCut()",returning="result")
26 public void logReturn(JoinPoint joinPoint,Object result){
27 System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
28 }
29 //joinPoint必须在返回值前面!!
30 @AfterThrowing(value="pointCut()",throwing="exception")
31 public void logException(JoinPoint joinPoint,Exception exception){
32 System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");
33 }
34}

  

通知方法:

@Aspect声明这是一个切面类

前置通知(@Before):logStart:在目标方法(div)运行之前运行

后置通知(@After):logEnd:在目标方法(div)运行结束之后运行(无论方法正常结束还是异常结束)

返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行

异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行

环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.procced())

3 将切面类和业务逻辑类(目标方法所在类)都加入到容器中;

```java
1@EnableAspectJAutoProxy
2@Configuration
3public class MainConfigOfAOP {
4
5 //业务逻辑类加入容器中
6 @Bean
7 public MathCalculator calculator(){
8 return new MathCalculator();
9 }
10
11 //切面类加入到容器中
12 @Bean
13 public LogAspects logAspects(){
14 return new LogAspects();
15 }
16}
```

给配置类中加 @EnableAspectJAutoProxy 【开启基于注解的aop模式】!!!

4 测试

 

1public class IOCTest_AOP {
2
3 @Test
4 public void test01(){
5 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
6
7 //1、不要自己创建对象
8// MathCalculator mathCalculator = new MathCalculator();
9// mathCalculator.div(1, 1);
10 MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
11
12 mathCalculator.div(1, 0);
13
14 applicationContext.close();
15 }
16
17}

  

只有在spring容器内的对象才能使用aop功能,所以使用的时候不能自己new一个对象,而是从容器获取!!!

运行结果:

1div运行。。。@Before:参数列表是: {[1, 1]}
2MathCalculator. . .div. . .
3div结束。。。@After
4div正常返回。。。@AfterReturning:运行结果: {1}

执行过程及源码解析
平时看注解的源码有一个小窍门,跟着源码进去会发现,该注解会实现了什么类,或者注入了某些组件,把注入组件的功能,跟注入的时间点搞清楚了,那么该功能的逻辑就会变得清晰


@EnableAspectJAutoProxy是什么?
@Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar

利用AspectJAutoProxyRegistrar自定义给容器中注册bean;BeanDefinetion

internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator


给容器中注册一个AnnotationAwareAspectJAutoProxyCreator;

跟着继承树:
AnnotationAwareAspectJAutoProxyCreator->AnnotationAwareAspectJAutoProxyCreator->AspectJAwareAdvisorAutoProxyCreator->AbstractAdvisorAutoProxyCreator->AbstractAutoProxyCreator

 

通过他的实现可以发现,它是一个后置处理器,并且也是factoryawrae接口的实现类
AnnotationAwareAspectJAutoProxyCreator注册过程

最后老规矩的总结一下(也相当重要!)
@EnableAspectJAutoProxy 开启AOP功能

@EnableAspectJAutoProxy 会给容器中注册一个组件
AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;

容器的创建流程:

registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象

finishBeanFactoryInitialization()初始化剩下的单实例bean

组件创建完之后,判断组件是否需要增强

执行目标方法:

代理对象执行目标方法

CglibAopProxy.intercept();

正常的执行顺序:前置通知-》目标方法-》后置通知-》返回通知

出现异常时:前置通知-》目标方法-》后置通知-》异常通知
?
包括但不限于:分布式架构、高可扩展、高性能、高并发、Jvm性能调优、Spring,MyBatis,nginx源码分析,Redis,ActiveMQ、Mycat、Netty、Kafka、mysql、Zookeeper、Tomcat、Docker、Dubbo、Nginx等多个知识点高级进阶干货面试题集,简历模板等三千多G资料包,关注回复DD无套路免费领取,助您从0到1

技术图片

 

 技术图片

 

以上是关于Spring-AOP注解开发的主要内容,如果未能解决你的问题,请参考以下文章

深入理解spring-AOP注解的底层实现原理

注解实现的spring-aop

Spring-AOP学习笔记-04 注解配置

spring-aop的简单实例注解版

spring——使用注解开发

Spring-AOP用法总结