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>中的属性或 ...
随机推荐
- 编译安装nginx时配置开机自启
详细编译安装nginx请参考[Nginx目录结构与配置文件详解]以及[Nginx安装部署],在这里就进行简单安装 安装Nginx 环境介绍 操作系统: [root@localhost ~]# cat ...
- 【解决】OCI runtime exec failed......executable file not found in $PATH": unknown
[问题]使用docker exec + sh进入容器时报错 [root@localhost home]# docker exec -it container-test bash OCI runtime ...
- POJ 2559 Langest Rectangle in a Histogame
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rec ...
- 曹工说Spring Boot源码系列开讲了(1)-- Bean Definition到底是什么,附spring思维导图分享
写在前面的话&&About me 网上写spring的文章多如牛毛,为什么还要写呢,因为,很简单,那是人家写的:网上都鼓励你不要造轮子,为什么你还要造呢,因为,那不是你造的. 我不是要 ...
- Centos7.2 下DNS+NamedManager高可用部署方案完整记录
Centos7.2 下DNS+NamedManager高可用部署方案完整记录 之前说到了NamedManager单机版的配置,下面说下DNS+NamedManager双机高可用的配置方案: 1)机器环 ...
- Django开发登录功能实战
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:凡夫俗子66 Django 如果是定义函数写登录路由,需要判断请求方法 ...
- jqurey(尺寸,css操作,效果,遍历)
尺寸: height():设置或返回元素的高度(不包括内边距.边框或外边距). width():设置或返回元素的宽度(不包括内边距.边框或外边距). 例如: $("#box").h ...
- Python利用PyExecJS库执行JS函数
在Web渗透流程的暴力登录场景和爬虫抓取场景中,经常会遇到一些登录表单用DES之类的加密方式来加密参数,也就是说,你不搞定这些前端加密,你的编写的脚本是不可能Login成功的.针对这个问题,现在有 ...
- LAMP两种模式
[LAMP] Linux(Centos)LAMP环境搭建,LAMP源码安装及LAMP架构原理详解 Wish_亮关注2人评论9469人阅读2018-08-20 01:33:10 本章blog主要介绍 ...
- Python3之Django的Cookie与Session的使用
一.Cookie的使用 1.设置Cookie url.set_cookie("tile","zhanggen",expires=value,path='/' ) ...