码迷,mamicode.com
首页 > 编程语言 > 详细

Spring-AOP注解开发

时间:2020-02-29 12:57:27      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:bsp   creat   roc   doc   nginx   turn   mat   net   factor   

微信公众号: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注解开发

标签:bsp   creat   roc   doc   nginx   turn   mat   net   factor   

原文地址:https://www.cnblogs.com/lvbl/p/12382290.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!