Spring学习的第三天
- 问题分析:在刚开始进行银行转账案例时,会获取四个连接,分别是查询接入、转出账户、更新转入、转出账户。这样会使转账不同步,如果某一处出现异常,前面的代码执行了,而后面的更新却没执行,导致一个账户加钱而另一个账户却没有减钱。
- 解决方法:将其整个过程只弄成一个连接,需要使用ThreadLocal对象把Connection和当前线程绑定,从而使一个线程中只有一个能控制事务的对象。
- 事务的控制应该是在业务层,需要用到两个工具类,关于线程绑定连接的和事务管理的,用起来非常麻烦。需要用到动态代理技术,将事务管理的方法进行增强,使得被代理对象的任何方法都会经过该方法。
第三天学习的主题: AOP面向切面编程
定义:通过预编译的方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP为OOP的延续,是函数式编程的一种衍生泛型。
简单来说就是把程序的重复代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对已有方法进行增强。
AOP的作用:在程序的运行期间,不修改源码对已有方法进行增强。
优势:减少重复代码,提高开发效率,维护方便。
AOP的实现方式:使用动态代理的技术。
*Spring中的AOP[重点]
说明:学习Spring的AOP,就是通过配置的方式,实现动态代理。
相关术语:
- JoinPoint(连接点):指被拦截到的点,在spring中,这些点指的是方法,因为spring只支持方法类型的连接点。
- PointOut(切入点):切入点指我们要对哪些JoinPoint进行拦截。
- Advice(通知/增强):通知指拦截到JoinPoint之后要做的事情。通知的类型:前置通知、后置通知、异常通知、最终通知、环绕通知。
- 前置通知:method.invoke()前面执行
- 后置通知:method.invoke()之后执行
- 异常通知:在catch()里的为异常通知
- 最终通知:在finally()里的为最终通知
- 环绕通知:整个动态代理过程执行的整个invoke方法在执行就是环绕通知,在环绕通知中会有明确的切入点方法调用
- Introduction(引介):引介是一种特殊的通知在不修改代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field。
- Target(目标对象):代理的目标对象,也就是被代理的对象。
- Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。
- Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类。
- Aspect(切面):是切入点和通知(引介)的结合。
学习spring中的AOP要明确的事:
- 开发阶段(我们要做的)
- 编写核心业务代码(开发主线)
- 把公共代码抽取出来,制作成通知(开发阶段最后再做)
- 在配置文件中,声明切入点与通知间的关系,即切面
- 运行阶段(spring框架来完成)
spring框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。
spring基于xml的AOP配置步骤:
- 把通知bean也交给spring来管理;
- 使用aop:config标签表明开始aop的配置;
- 使用aop:aspect标签表明配置切面(id属性:唯一标识符,ref属性:指定通知类bean的Id)
- 在aop:aspect的内部使用对应的标签来配置通知类型
- 关于切入点表达式:
- 访问修饰符可以省略
- 返回值可以使用通配符*表示任意返回值
- 包名可以使用通配符表示任意包,但是有几级包就需要写几个*
- 包名可以使用..表示当前包及其子包
- 类名和方法名都可以使用*来实现通配
- 可以使用..表示有无参数均可,有参数可以表示任意参数类型以及任意个数
实际开发中切入点表达式的通常写法为切换到业务层实现类下的所有方法:
* xx.xx.service.impl.*.*(..)
通用化切入点表达式:配置切入点表达式,使用aop:pointcut,该标签写在aop:aspect标签外面,此时变成了所有切面可用,但是要写在前面。id属性用于指定表达式的唯一标识,expression属性用于指定切入点表达式的内容。
在aop:aspect标签内用pointcut-ref属性进行接收。
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.itheima.service.Impl.*.*(..))"/>
<aop:aspect id="logAdvice" ref="txManager">
<aop:before method="beginTransaction" pointcut-ref="pt1"></aop:before>
<aop:after-returning method="commit" pointcut-ref="pt1"></aop:after-returning>
<aop:after-throwing method="rollback" pointcut-ref="pt1"></aop:after-throwing>
<aop:after method="release" pointcut-ref="pt1"></aop:after>
</aop:aspect>
</aop:config>
spring中的环绕通知:它是spring框架为我们提供的一种可以在代码中手动控制增强方法何时执行的方式。
可是为什么当我们配置环绕通知之后,切入点方法没有执行,而各种通知的方法执行了?原因就是在底层动态代理的环绕通知代码中,发现动态代理的环绕通知有明确的切入点方法调用,而我们配置的方法没有。
spring基于注解的AOP配置步骤:
@Aspect注解声明该类为切面类;
@pointcut声明切入点表达式
在使用注解AOP配置的时候,普通的四个通知执行调用顺序有问题,而环绕通知基于注解没有问题,可以使用。
在使用纯注解的配置时,注意在配置类上加上这个注解@EnableAspectJAutoProxy(让spring支持基于注解AOP)
Spring学习的第三天的更多相关文章
- Spring学习之旅(三)--装配Bean
装配 Bean 的方式 在 XML 中进行显式配置 在 Java 中进行显式配置 隐式的 Bean 发现机制和自动装配 Spring 提供了以上三种方式进行 Bean 的配置,可以根据自己的需求选择一 ...
- Spring学习总结(三)——Spring实现AOP的多种方式
AOP(Aspect Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的横向多模块统一控制的一种技术.AOP是OOP的补充,是Spring框架中的一个 ...
- Spring 学习指南 第三章 bean的配置 (未完结)
第三章 bean 的配置 在本章中,我们将介绍以下内容: bean 定义的继承: 如何解决 bean 类的构造函数的参数: 如何配置原始类型 (如 int .float 等) .集合类型(如 ja ...
- Spring学习进阶 (三) Spring AOP
一.是什么AOP是Aspect Oriented Programing的简称,最初被译为“面向方面编程”:AOP通过横向抽取机制为无法通过纵向继承体系进行抽象的重复性代码提供了解决方案.比如事务的控制 ...
- 我的Spring学习记录(三)
学习了AOP之后就可以应用一下了,所以这次我们了解一下Spring的声明式事务. 事务在我们的很多方面都可以体现,就拿我们平时的买卖活动,或者是银行的转账来说,这些活动要么是成功,要么是失败,比如:张 ...
- Spring学习笔记(三)--Convert System设计
一.概述 转换系统是不同范式系统间交互常常会需要碰到的,如WEB 中HTTP KV文本流到对象的转换和对象到http KV文本流的转换:还有对象到关系型DB和关系型DB到对象之间的转换(ORM). 一 ...
- Spring学习笔记(三)—— 使用注解配置spring
一.使用步骤 1.1 导包 1.2 为主配置文件引入新的命名空间(约束) 在applicationContext.xml中引入context约束 1.3 编写相关的类 public class Use ...
- Java 系列之spring学习--注解(三)
一.注解 使用注解之前要开启自动扫描功能 <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...
- Spring 学习笔记(三):Spring Bean
1 Bean配置 Spring可以看做是一个管理Bean的工厂,开发者需要将Bean配置在XML或者Properties配置文件中.实际开发中常使用XML的格式,其中<bean>中的属性或 ...
随机推荐
- HDU1846 Brave Game(巴什博弈)
十年前读大学的时候,中国每年都要从国外引进一些电影大片,其中有一部电影就叫<勇敢者的游戏>(英文名称:Zathura),一直到现在,我依然对于电影中的部分电脑特技印象深刻. 今天,大家选择 ...
- CSUOJ 1952 合并石子
现在有n堆石子,第i堆有ai个石子.现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数.求合并所有石子的最小代价. Input 第一行包含一个整数T(T<=50 ...
- python pyHook安装
Hook安装 哇 这东西可真费劲 主要有pyhook和pyhook3 两种 每个都要根据系统版本和python版本 分成各种小版本 具体安装 一.可以在cmd 中输入 pip install pyh ...
- numpy的基本API(二)——维数操作
numpy的基本维数操作API iwehdio的博客园:https://www.cnblogs.com/iwehdio/ 1.np.copyto(dst, src) copyto方法将数组src复制到 ...
- Dubbo源码分析之SPI(二)
一.概述 本篇文章是dubbo SPI源码分析的第二篇,接着第一篇继续分析dubbo SPI的内容,我们主要介绍 getDefaultExtension() 获取默认扩展点方法. 由于此方法比较简单, ...
- Java中真的只有值传递么?
Java中真的只有值传递么? (本文非引战或diss,只是说出自己的理解,欢迎摆正心态观看或探讨) 回顾值传递和引用传递 关于Java是值传递还是引用传递,网上有不一样的说法. 1.基本类型或基本类型 ...
- Nginx学习一路向西
Nginx 学习一路向北 Java大猿帅成长手册,GitHub JavaEgg ,N线互联网开发必备技能兵器谱 1. Nginx简介 1.1 Nginx 概述 NGINX是一个免费.开源.高性能.轻量 ...
- Ubuntu修改时间
Ubuntu修改时区和更新时间 先查看当前系统时间 date -R 结果时区是:+0000 我需要的是东八区,这儿显示不是,所以需要设置一个时区 运行 tzselect 在这里我们选择亚洲 Asia, ...
- hexo + next 搭建博客时Cannot GET /tags/问题处理
原来是要修改新建的index.md文件,不仔细. 此外,愈发觉得百度和谷歌搜索同一问题的差距,谷歌更适合程序员! https://www.zhihu.com/question/29017171 这个可 ...
- 全平台轻量开源verilog仿真工具iverilog+GTKWave使用教程
前言 如果你只是想检查Verilog文件的语法是否有错误,然后进行一些基本的时序仿真,那么Icarus Verilog 就是一个不错的选择.相比于各大FPGA厂商的IDE几个G的大小,Icarus V ...