Spring—Aop暨初开博客感想

终于拥有属于自己的博客了,记录一点心得体会吧,生活的后花园。

本人大二,双非本科在读。很早之前就想开博客了,这种想法在去年暑假,也就是2022年的夏天尤为强烈。当时爱上了算法,每天都要刷不少的题,虽然有的是看着大佬们的题解才拿到思路的,但慢慢积累下来也养成了不少算法思维。打开博客对我来说真不是一件容易的事情,不知道写什么,写出来的东西入不了大家的眼怎么办,单纯浪费了时间怎么办...当时啊想了很多劝自己打消开博的念头,但直到现在,我才发现,如果能把当时记录下来,如今的我可以说是拥有一笔不小的财富了。现在又是一次机会了,还是抓住吧。这边就记录一点平时的学习心得和一些感悟吧,便于自己及时总结归纳,时不时也能写一些生活碎片,计划是每天晚上写一点,没有意外的每天都会有,欢迎技术交流!

 


 

最近在学习Spring,前几天都是混乱的,学一会歇一会,没有很强的连贯性。现在事情都忙完了,终于有时间空下来定心学习了。前面学习中,首先了解到了Spring的优点,在开发中能做到充分解耦,简化开发,同时提供大量的开发工具。目前学完了Spring的核心容器部分,包括有IoC(控制反转)和DI(依赖注入),Bean的配置文件装配和注解开发,见识尚为短浅,学无止境,虚心向前。下面来整理一下今天学到的AOP(面向切面编程)。

 

什么是AOP?

我的理解是,AOP是将一个共同的功能抽取出来,然后分配给需要他们的方法,在不惊动原有的设计的情况下,实现功能的修改。在面向对象的编程中,我们需要为某个事务编写方法时,一般都会需要什么写什么,对于完全不同的事务来说,效率很高,然而如果遇到有共性的事务时,操作就变得麻烦了起来。要对每一种事务都书写相同的方法,即使怎么熟练ctrl+cv开发,都会被这复杂的步骤折服。而AOP则解决了这一办法,例如在每次查找操作后记录操作者,操作的对象,操作的时间...就可以将其单独写为一个方法,在AOP中,这种方法称为通知。它将互通的代码抽取出,在程序运行是将其分散到需要执行的地方。区别于继承的地方在于,该过程是一种采取横向抽取机制的方式,而继承采取的是纵向的方式。生动点,或许可以比作一个家族,从爷爷到儿子到孙子,他们都继承这这个家族的Y染色体,一脉相承,这就是继承,而AOP实现的就是X染色体的发放,例如这个爷爷有3个儿子,那么无论如何,奶奶的X染色体都会发放给他们的3个儿子,这比喻应该够生动了吧!这样一来,AOP是什么就清楚了,要知道的是它能提高开发效率,增强代码的可维护性(如果要修改方法,很简单,修改通知即可),这是它成为Spring的核心思想之一的重要原因!

AOP有什么?

在大致知道AOP负什么责任之后,有必要来了解一下AOP里面有什么。

  • 切面(Aspect):既然被称为面向切面编程,切面的定义尤为重要。切面是指封装的用于横向插入的类。在配置文件中使用<bean>元素指定后,方可被Spring容器识别。
  • 连接点(JointPoint):是指在程序执行过程中的某个阶段点。
  • 切入点(PointCut):是指切面和程序的交叉点,书中描述为需要处理的连接点。切入点指的是类或者方法名,例如应用通知到所有的含有select的方法中时,满足该规则的方法都是切入点。
  • 通知增强处理(Advice):AOP在特定的切入点执行增强的处理,在定义好切入点的地方所要执行的代码。可以理解为切面类中的方法。
  • 目标对象(Target Object):指所有被通知到的对象,他们有被增强的功能可以实现!(AOP核心概念)
  • 代理(Proxy):将通知应用到目标对象后,被动态创建的对象。(AOP核心概念)
  • 织入(Weaving):将切面代码插入到目标对象上,从而生产代理对象的过程。

AOP的工作流程是什么?

  • Spring容器的启动
  • 读取所有切面配置中的切入点
  • 初始化bean,判定bean对应的类中的方法是否匹配到任意的切入点

  匹配失败则创建一个新对象

  匹配成功,则创建原始对象(目标对象)的代理对象(织入)

  • 获取bean执行方法

  获取bean,调用方法并执行,完成操作。

  获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,便完成了操作

Spring中AOP的本质是什么:代理模

在main函数中运行如下代码(AOP配置已完成),查看此时目标对象的class。

ApplicationContext ctx=new AnnotationConfigApplicationContext(SpringConfig.class);
 BookDao bookDao= ctx.getBean(BookDao.class);
 bookDao.update();
 System.out.println(bookDao);
 System.out.println(bookDao.getClass());

 

在main函数中运行如下代码(AOP配置已完成),查看此时目标对象的class。可以发现最终用的是代理对象。(在AOP中对最终的对象的toString方法进行了重写,所以会看到第三行的内容)。

AOP切入点表达式

切入点:要增强的方法

切入点表达式:要增强的方法的描述方式

描述方式一:执行xx包下的xx接口中的无参数方法

描述方式二:执行xx.impl包下的xx类中的无参数方法

格式:动作关键词(访问修饰符号 返回值 包名.类/接口.方法名(参数)异常名)

 


 

书接上文(已经是第二天了)

本来昨天想着写一点发出去的,没想到就点了个保存草稿,想着一觉醒来会不会暴涨几个阅读来着,呵呵,还是不熟悉啊。在写总结前先记录一下今天的轶事。。写代码练练的时候,发现在Test中自动装配莫名报错了,网上翻遍了资料,对照原版一个个看,愣是看了十几分钟没看出来哪边错了。后来想着自动装配得先有Bean啊,让CompententScan扫一下我的Service包不就好了,纳尼?不存在?原来如此,在写包的时候居然把Service包写到主包外面去了,罪过罪过。。。


 

昨天说到AOP的切入点表达式,其中通配符的使用可以说是多种多样,可以应对不同的开发需求。今天进一步深入学习AOP。

AOP的通知类型

  • 前置通知:在原始方法执行前,注解为@Before
  • 后置通知:在原始方法执行后,注解为@After
  • 环绕通知:环绕通知最为重要,在原始方法运行前后都会执行,注解为@Around。环绕通知要依赖形参ProceedingJoinPoint才能对原始方法进行调用(同时它也只能位于形参的第一位),正因为如此,也可隔离原始方法的调用。如果需要返回值,则可以通过设置一个Object对象来接受返回值,同时也能对原始方法中抛出的异常进行处理。
  • 返回后通知:在原始方法运行完毕后执行
  • 抛出异常后通知:在原始方法抛出异常后执行

获取通知中的数据

  • 获取切入点方法的参数:获取切入点方法的返回值:①在返回后通知②使用环绕通知
    •   JoinPoint:适用于前置,后置,返回后和抛出异常后通知
    •   ProceedJoinPoint:适用于环绕通知
  • 获取切入点方法的返回值:①在返回后通知②使用环绕通知
  • 获取切入点方法运行异常:①抛出异常后通知②环绕通知

由此可见环绕通知是有多么重要!

那么关于AOP的学习到这里差不多就结束了,所学甚浅,还望看管海涵,有错误还请斧正,明天见啦!

 

作者:GaryRoyal原文地址:https://www.cnblogs.com/garyroyal/p/17092223.html

%s 个评论

要回复文章请先登录注册