>

Spring知识总括

- 编辑:www.bifa688.com -

Spring知识总括

一、Spring简述
    Spring是二个支行的JavaSE/EEfull-stack(一站式)轻量级开源框架,Spring致力于提供壹种情势管理你的事情对象,Spring的基本点
目标是使JavaEE易用和促进好编制程序习贯,Spring致力于J二EE应用的各层的消除方案,而不是只是专注于某1层的方案,Spring贯穿表现
层、业务层及持久层。但是,Spring并不想代替这些已部分框架,而是与它们无缝地组合。
二、Spring种类布局
    Spring框架是3个支行架构,它包涵一层层的作用因素并被分成大致二十五个模块。这一个模块分为Core Container、Data Access/Integration
Web、AOP(Aspect Oriented Programming)、Instrumentation和测试部分;

1.1.1 什么是AOP

  • 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编制程序,通过预编写翻译方式和平运动行期动态代理达成程序作用的联合珍爱的一种能力。AOP是OOP的持续,是软件开辟中的贰个抢手,也是Spring框架中的二个首要内容,是函数式编程的一种衍生范型。利用AOP能够对业务逻辑的顺序部分实行隔绝,从而使得业务逻辑各部分之间的耦合度降低,进步程序的可重用性,同时压实了开支的效用。
  • AOP选拔横向抽出机制,代替了价值观纵向传承种类重复性代码
  • 杰出应用:事务处理、品质监视、安检、缓存 、日志等
  • Spring AOP使用纯Java达成,没有需求特意的编写翻译进度和类加载器,在运行期通过代办格局向指标类织入巩固代码
  • AspectJ是二个基于Java语言的AOP框架,Spring二.0发端,Spring AOP引进对Aspect的协助,AspectJ扩张了Java语言,提供了二个特别的编写翻译器,在编译时提供横向代码的织入

1. Spring MVC简介

  Spring MVC是java EE平台请求驱动类型的轻量级Web框架,使用了MVC设计情势的理念,spring框架的主要性优势之1正是分支架构,分层架构允许选用选用别的1个零件,同时也得以合二为1此外框架本领,譬喻:Struts二、Hibernate等

  Spring框架具备以下特征:

  壹. 利于解耦,简化开荒。通过spring3提供的IoC容器,能够将对象时期的依附关系交由Spring3说了算,防止编码所导致的程序过度耦合

  二. AOP编制程序的支持。通过Spring三提供的AOP功效,方便开展面向切面编制程序,大多不便于选取面向对象程序设计(OOP)达成的效用能够因此AOP轻松实现

  三. 表明式事务的支撑。通过阐明格局灵活地拓展事务管理,升高开销成效和材质

  四. 福利集成各个赏心悦目框架。

  Spring框架种种零部件的意义:

  一. 基本容器

  焦点容器提供Spring三框架基本的功效。大旨容器的最重要组件是BeanFactory和ApplicationContext。容器使用调控反转(IoC)格局将应用程序的配置和重视标准和实际的应用程序代码分开。

  2. Spring上下文

  Spring上下文是一个计划文件,向Spring框架提供上下文音讯。Spring上下文包罗集团服务,举个例子,校验、JNDI、EJB、电子邮件、国际化等

  3. Spring AOP

  通过安插管理天性,Spring AOP模块间接将面向切面包车型地铁编程功效集成到Spring框架中,pring AOP模块提供了事务管理服务。

  4. Spring DAO

   JDBC DAO抽象层提供了有含义的十二分档案的次序结构,可用该社团来治本11分管理和见仁见智数据库供应商抛出的荒谬音讯。

  5. Spring ORM

  Spring插入了若干个O奥迪Q7M框架,从而提供了O冠道M的工具,个中包含JDO、Hibernate、iBatisSQL Map。

图片 1
  (一)大旨容器(Core Container)
    一:Core和Beans模块提供了Spring最基础的成效,提供IOC 和重视注入特性。这里的底子概念是BeanFactory,它提供对Factory
  形式的经文完成来化解对程序性单例形式的须求,并真正地同意你从程序逻辑中分别出依赖关系和配备。
    二:Context模块基于 Core和 Beans来营造,它提供了用一种框架风格的办法来走访对象,某个像JNDI注册表。Context封装包继
  承了 beans 包的职能,还增添了国际化(I1八N),事件传播,财富装载,以及透明创立上下文,比如通过servlet容器,以及对多量
  JavaEE个性的支撑,如 EJB、JMX。核心接口是ApplicationContext。
    三:Expression Language,表达式语言模块,提供了在运维时期查询和操作对象图的兵不血刃力量。援助访问和改换属性值,方法调
  用,辅助访问及修改数组、容器和索引器,命名变量,扶助算数和逻辑运算,辅助从Spring容器获取Bean,它也支撑列表投影、选
  择和一般的列表聚合等。
 (2)数据访问/ 集成都部队分(Data Access/Integration)
    壹:JDBC模块,提供对JDBC的抽象,它可免去冗长的JDBC编码和剖判数据库商家特有的错误代码。
    贰:O奥迪Q5M模块,提供了常用的"对象/关系"映射API的集成层。 个中囊括JPA、JDO、Hibernate和iBatis 。利用O昂科拉M封装包,可以混
  合使用具备Spring提供的特点开始展览"对象/关系"映射,如轻易声明性 事务管理。
    叁:OXM模块,提供叁个援助Object和XML实行映射的抽象层,个中囊括JAXB、Castor、XMLBeans、JiBX 和 XStream。
    4:JMS模块,提供1套"新闻生产者、消费者"模板用于越发简便易行的运用 JMS,JMS 用于在三个应用程序之间,或布满式系统中发
  送音信,举行异步通讯。
    5:Transaction模块,扶助程序通过轻松评释性事务管理,只借使Spring管理对象都能获取Spring管理作业的益处,就算是POJO,
  也足认为他们提供业务。
 (3)Web
    一:Web-Socket模块,WebSocket protocol是HTML伍1种新的合计。它完成了浏览器与服务器全双工通讯,spring扶助webSocket通信。
    二:Web模块,提供了根基的web功效。譬喻多文件上传、集成IOC容器、远程进度访问、以及Web Service协理,并提供贰个
  RestTemplate类来提供方便的Restful services访问
    叁:Web-Servlet模块,提供了Web应用的Model-View-ControllerMVC)完成。Spring MVC框架提供了基于表明的乞求能源流入、更
  简单的多少绑定、数据印证等及壹套特别易用的JSP标签,完全无缝与Spring其余本事同盟。
    四: Web-Portlet模块,提供了在Portlet碰到下的MVC完结。
 (4)AOP
    1:AOP模块,提供了适合AOP结盟正式的面向方面包车型客车编制程序完成,让你能够定义如方法拦截器和切入点,从逻辑上讲,可以收缩代码
  的功能耦合,清晰的被分别开。而且采取源码级的元数据功用,仍是能够将各类表现消息统一到您的代码中 。
    贰:Aspects模块,提供了对AspectJ的并轨。
    3:Instrumentation模块, 提供部分类级的工具协助和ClassLoader级的落到实处,能够在有个别一定的应用服务器中选用。
 (5)Test
    Test模块,提供对运用JUnit和TestNG来测试Spring组件的帮助,它提供一样的ApplicationContexts并缓存那么些上下文,它还是能
  提供一些mock对象,使得你能够单独的测试代码。
三、Spring的优点
    方便解耦,简化开采
      Spring就是一个大工厂,可以将有着指标创制和依靠关系维护,交给Spring管理;
    AOP 编制程序的支撑
      Spring提供面向切面编制程序,能够便宜的兑现对先后开始展览权力拦截、运行监察和控制等效率
    注明式事务的协理
      只供给经过布置就足以做到对事情的管理,而没有必要手动编制程序
    方便程序的测试
      Spring对Junit四协助,能够经过申明方便的测试Spring程序方便集成各样优异框架Spring不排外各类漂亮的开源框架,其内部
    提供了对种种特出框架(如:Struts、Hibernate、MyBatis、Quartz 等)的直接帮忙;
    下跌JavaEE API的选取难度  
      Spring对 JavaEE开辟中那多少个难用的一些API(JDBC、JavaMail、远程调用等),都提供了包装,使那么些API应用难度大大下跌。
四、ApplicationContext文件与BeanFactory类

一.1.贰 AOP实现原理

  • aop底层将选替代理体制实行落到实处。
  • 接口 达成类 :spring接纳 jdk 的动态代理Proxy。
  • 完毕类:spring 采取 cglib字节码增强。

二. Spring IoC(调整反转)

  IoC是Inversion of Control的缩写,正是经过IoC容器来兑现指标组件的装配和管制。也正是说,全数组件都是庸庸碌碌的,全数的零部件初阶化和调用都由IoC容器担当。

  Spring IoC平日用到2个设计形式——工厂格局,工厂格局提供创制对象的接口。

  Spring框架三个最基本的包是:org.springframework.beans.factory(首要接口是BeanFactory)和org.springframework.context(首要接口是ApplicationFactory)

  IoC重要组件:

  1. Beans

  Beans指项目中提供专业作用Bean,即IoC容器要管住的Bean,Bean能够分包部分品质的getter和setter方法,也足以涵盖其余方法

  二. 配备文件

  Spring对Bean的管制在配置文件中举行.Bean的配备文件是一个xml文件,他普通命名称叫beans.xml、applicationContext.xml等,配置文件包罗Bean的id、类、属性及其值。IoC容器通过Bean的id从Bean配置文件中拿走Bean的类,并生成该配置文件的一个目的。

  三. BeanFactory接口及其相关类

  BeanFactory选择了工厂设计方式,即Bean容器方式,担任读取Bean的配置文件,管理对象的转换、加载,维护对象时期的依据关系,担任Bean对象的生命周期。

  org.springframework.beans.factory.BeanFactory是3个世界级接口,它涵盖管理Bean的各个措施,比如:getBean(String name),,遵照Bean的id生成Bean的指标

  肆. ApplicationContext接口及其有关类

  ApplicationContext接口提供高等功效的器皿,比如:提供访问能源文件的更便利的法子,帮忙国际化等

  流入的二种方法:

  一. 安装注入

  设置注入是通过setter方法注入被调用者的实例

  2.构造流入

  利用构造方法来设置信赖注入

图片 2
    壹. ApplicationContext它是扩张BeanFactory接口;
    二. BeanFactory它接纳延迟加载的方案,唯有真正在getBean时才会实例化Bean在付出中咱们一般选用的是 ApplicationContext,
   真正使用的是事实上现类,FileSystemXmlAppliCationContext依照文件路线获取,ClassPathXmlApplicationContext 依据类路线获
   取;
    三. AppliCationContext它会在布局文件加载时,就能先河化Bean并且ApplicationContext它提供不一样的应用层的Context达成。
5、Bean的成效域
    在bean评释时它有3个scope(功用域)属性,它是用以描述bean的效用域。
        可取值有:
        singleton:单例 代表在spring ioc容器中只有2个Bean实例(私下认可的scope)
        prototype 多例 每便从spring容器中取得时,都会重返贰个新的实例
        request 用在web开发中,将bean对象request.setAttribute()存储到request域中
        session 用在web开发中,将bean对象session.setAttribute()存储到session域中
    在开如常用的值是singleton与prototype。
6、Bean的生命周期

1.1.3 AOP术语

一.target:指标类,须要被代理的类。举个例子:UserService二.Joinpoint:所谓连接点是指这么些大概被拦截到的方法。举例:全数的方法三.PointCut 切入点:已经被升高的连接点。比方:addUser()4.advice 布告/加强,巩固代码。举例:after、before

  1. Weaving:是指把提升advice应用到指标对象target来创制新的代办对象proxy的进程.

6.proxy 代理类.

  1. Aspect: 是切入点pointcut和公告advice的重组二个线是一个新鲜的面。壹个切入点和3个通报,组成成一个独辟蹊径的面。

图片 3

3. Spring AOP(面向切面编制程序)

  AOP为Aspect Oriented Programming的缩写,即面向切面编制程序(也叫面向方面),是一种能够通过预编写翻译情势和平运动行期动态代理达成在不修改源代码的情形下给程序动态统1加多效果的壹种能力。

  使用AOP技能,可以将1部分系统性相关的编制程序专门的职业,独立提抽出来,独立完结,然后通过切面切入进系统。从而制止了在业务逻辑的代码中混入多数的连串有关的逻辑——比方权限管理,事物管理,日志记录等等。这一个系统性的编制程序事业都足以独立编码达成,然后通过AOP本事切入进系统就能够。

  AOP分为静态AOP和动态AOP。静态AOP是指AspectJ完成的AOP,他是将切面代码直接编写翻译到Java类文件中。动态AOP是指将切面代码举办动态织入达成的AOP。Spring的AOP为动态AOP,达成的本事为:JDK提供的动态代理本事 和 CGLIB(动态字节码巩固本事)。就算落到实处技艺不均等,但皆以根据代理格局,皆以生成1个代理对象。

图片 4
    1. instantiate bean 对象实例化;
    2. populate properties 封装属性;
    3. 如果 Bean 实现 BeanNameAware 执行 setBeanName;
    4. 借使 Bean 达成 BeanFactoryAwar 或 ApplicationContextAwar 设置工厂 setBeanFactory 或上;
       下文对象 setApplicationContext;
    5. 壹旦存在类达成 BeanPostProcess(后处理 Bean),实践postProcessBeforeInitialization;
    6. 如果 Bean 实现 InitializingBean 执行 afterPropertiesSet;
    7. 调用自定义的 init-method 方法;
    八. 譬喻存在类达成 BeanPostProcessor(管理 Bean),实施postProcessAfterInitialization;
    玖. 推行职业管理;
    10. 如果 Bean 实现 DisposableBean 执行 destroy;
    1壹. 调用自定义的 destroy-method;
七、AOP
    1. 简述
        AOP(面向切面编制程序)通过预编写翻译格局和平运动行期动态代理完成程序作用的联结保养的一种本领。AOP是(面向对象编制程序)的继续,
    是软件是Spring框架中的一个器重内容,是函数式编制程序的1种衍生范型。利用AOP能够对作业逻辑的各样部分实行隔开,从而使
    得业务逻辑各部分之间的耦合度下落,升高程序的可重用性,同时提升了开支的效能。
        AOP是一个概念,并未设定具身体语言言的完结,它能克制那个唯有单传承特性语言的缺陷,spring二.0之后整合AspectJ第1
    方AOP技术。AspectJ是一个面向切面包车型客车框架,它增加了Java语言。AspectJ定义了AOP语法所以它有一个特地的编写翻译器用来生成遵
    守Java字节编码标准的Class文件。
      一.一 首要意义
          日志记录,品质计算,安控,事务管理,极度管理等等
      一.二 重要意图
          将日志记录,品质总括,安控,事务处理,十分处理等代码从事情逻辑代码中划分出来,通过对这几个作为的分手,笔者
      们盼望能够将它们独立到非教导业务逻辑的不2秘技中,进而更改这么些行为的时候不影响职业逻辑的代码。
    2. AOP与OOP区别
       OOP针对工作管理进度的实体及其性质和表现实行抽象封装,以获得更加的清晰高效的逻辑单元区划。而AOP则是针对专门的学问管理过
    程中的切面举办提取,它所面对的是管理进度中的某些步骤或阶段,以获得逻辑进程中各部分之间低耦合性的割裂效果。那二种
    设计观念在目的上有着本质的差别。
    三. 有关术语
      三.壹 目的对象(target)
          指的是急需被增加的靶子,由于aop是通过代办格局达成,从而那么些指标恒久是被代理对象。
      3.2 连接点(join point)
          所谓连接点是指那二个被挡住到的点,在spring中那些点指的是方法,spring只帮忙方式类型的连接点。
      3.3 切入点(pointcut)
          表示壹组joint point,这几个joint point或是通过逻辑关系组合起来,或是通过通配、正则表明式等办法集中起来,它定
      义了相应的Advice将要产生的地方大概说切入点是指我们要对怎么样连接点举办拦阻的定义。
      3.4 通知(advice)
          所谓通告是指拦截到连接点之后所要做的事务正是打招呼,通告分为前置通告,前置文告,非常公告,最终公告,环绕布告
      Advice定义了在pointcut里面定义的程序点具体要做的操作。
      3.5 引介(introduction)
          引导介绍是一种相当的照看,在不修改类代码的前提下,introduction能够在运营期为类动态地丰盛一些措施或性质。
      3.6 切面(aspect)
          是切入点和布告的组合。
      3.7 织入(weaving)
          织入是多少个进度,是将切面应用到目的对象从而创建出AOP代理对象的进度,织入能够在编写翻译期,类装载期,运转期进行。
      Spring选择动态织入,而aspectj选取静态织入。
      3.8 代理(Proxy)
          3个类被AOP织入巩固后,就生出一个结实代理类。
    四.AOP的动态代理
        AOP的平底实现正是动态代理,一般AOP分为静态AOP和动态AOP。静态AOP是指AspectJ达成的AOP,他是将切面代码直接编写翻译到
    Java类文件中。动态 AOP是指将切面代码实行动态织入完成的AOP。Spring的AOP为动态AOP,达成的本领为:JDK提供的动态代理
    技能和CGLIB(动态字节码巩固技艺)。
      肆.一 JDK动态代理
          在JVM运营时,内部动态生成class字节码对象(即Class 对象),注:JDK动态代理只针对于接口操作。
      四.贰 CGLIB动态代理
          CGLIB是1个开源项目是3个高品质,高水平的Code生成类库,它能够在运行期扩张Java类与落到实处Java接口。CGLIB包的底
      层是通过运用二个小而快的字节码管理框架ASM,来调换字节码并生成新的类,单独接纳CGLIB,那么须要导入CGLIB的jar包还
      需求一个asm相关jar包,但是spring框架的spring-core.jar 包中已经集成了CGLIB与asm。
          注意:JDK动态代理只可认为接口去达成操作,而CGLIB动态代理可感到未有兑现接口的类去做代理,也足以为贯彻接口的类
      去做代理。CGLIB动态代理它可以为未有实现接口的类做代理,也得以为接口类做代理。
      如若目的对象,有接口,优先选择:JDK动态代理只,假诺指标对象,无接口,使用CGLIB动态代理。
    5.AOP的思想意识编制程序
        在思想的Spring AOP开拓中它支持坚实(advice)有八种:
            一. 内置公告指标措施实行前提升org.springframework.aop.MethodBeforeAdvice;
            二. 前置通知指标措施推行后拉长org.springframework.aop.AfterReturningAdvice;
            3. 环绕布告目标措施实行前后进行加强org.aopalliance.intercept.MethodInterceptor;
            四. 卓殊抛出文告目的措施抛出极其后的增加org.springframework.aop.ThrowsAdvice;
            5. 引导介绍通告在指标类中增加一些新的法门或性质org.springframework.aop.IntroductionInterceptor;
    6.Spring 整合aspectj框架实现AOP
        Aspect:切面 =切点 通告(两个切点与四个公告的咬合)
        AspectJ它是二个第二方框架,spring 从 2.0 后能够使用 aspectJ 框架的有些语法。
        AspectJ框架它定义的公告类型有多种:
            一. 放权文告 Before相当于BeforeAdvice;
            二. 前置公告 AfterReturning相当于AfterReturningAdvice;
            3. 围绕布告 Around也正是MethodInterceptor;
            肆. 抛出公告 AfterThrowing也就是ThrowAdvice;
            伍. 引导介绍公告 DeclareParents也就是IntroductionInterceptor;
            陆. 终极文告After不管是或不是足够,该公告都会实践,比较Spring的思想AOP Advice多了3个末段文告。
捌、Spring的事务管理
    Spring的事务管理的八个优点:
      1. 提供一样的对于分裂的事务管理的 API;
      2. 支撑表明式事务管理;
      三. 编制程序事务管理;
      四. 名特别降价的组合与Spring的数量访问:
    Spring的事务管理主要提供了多少个接口来形成:
      1. org.springframework.transaction.PlatformTransactionManager
        那是四个作业管理器,能够来挑选有关的阳台(jdbc hibernate jpa…)
      2. TransactionDefinition
        它定义事务的一些相关音信 比方:隔绝、传播、超时、只读
      3. TransactionStatus
        (1)PlatformTransactionManager
          平台专业处理器,在分歧的长久化层化解本领它的作业代码分歧等。
          JDBC 开发            

一.二.1 JDK动态代理

  • JDK动态代理 对“装饰者”设计情势简化。使用前提:必须有接口壹.目的类:接口 实现类2.切面类:用于存布告 MyAspect三.工厂类:编写工厂生成代理4.测试

图片 5

public interface UserService { public void addUser(); public void updateUser(); public void deleteUser();}

public class MyAspect { public void before(){ System.out.println; } public void after(){ System.out.println; }}

public class MyBeanFactory { public static UserService createService(){ //1 目标类 final UserService userService = new UserServiceImpl(); //2切面类 final MyAspect myAspect = new MyAspect(); /* 3 代理类:将目标类和 切面类 结合 --> 切面 * Proxy.newProxyInstance * 参数1:loader ,类加载器,动态代理类 运行时创建,任何类都需要类加载器将其加载到内存。 * 一般情况:当前类.class.getClassLoader(); * 目标类实例.getClass().get... * 参数2:Class[] interfaces 代理类需要实现的所有接口 * 方式1:目标类实例.getClass().getInterfaces() ;注意:只能获得自己接口,不能获得父元素接口 * 方式2:new Class[]{UserService.class} * 例如:jdbc 驱动 --> DriverManager 获得接口 Connection * 参数3:InvocationHandler 处理类,接口,必须进行实现类,一般采用匿名内部 * 提供 invoke 方法,代理类的每一个方法执行时,都将调用一次invoke * 参数31:Object proxy :代理对象 * 参数32:Method method : 代理对象当前执行的方法的描述对象 * 执行方法名:method.getName() * 执行方法:method.invoke * 参数33:Object[] args :方法实际参数 * */ UserService proxService = (UserService)Proxy.newProxyInstance( MyBeanFactory.class.getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //前执行 myAspect.before(); //执行目标类的方法 Object obj = method.invoke(userService, args); //后执行 myAspect.after(); return obj; } }); return proxService; }}

@Testpublic void demo01(){ UserService userService = MyBeanFactory.createService(); userService.addUser(); userService.updateUser(); userService.deleteUser(); }
Connection con=……;
con.setAutoCommit(false);//开启事务
con.rollback();
con.commit();

壹.二.二 CGLIB字节码巩固

  • 尚未接口,唯有实现类。
  • 采纳字节码巩固框架 cglib,在运作时 创制指标类的子类,从而对目的类进行加强。
  • 导入jar包:本人导包:核心:hibernate-distribution-三.陆.拾.Finallibbytecodecglibcglib-2.2.jar依赖:struts-2.3.15.3appsstruts2-blankWEB-INFlibasm-三.三.jarspring-core..jar 已经组成上述几个内容

图片 6图片 7图片 8

public class MyBeanFactory { public static UserServiceImpl createService(){ //1 目标类 final UserServiceImpl userService = new UserServiceImpl(); //2切面类 final MyAspect myAspect = new MyAspect(); // 3.代理类 ,采用cglib,底层创建目标类的子类 //3.1 核心类 Enhancer enhancer = new Enhancer(); //3.2 确定父类 enhancer.setSuperclass(userService.getClass; /* 3.3 设置回调函数 , MethodInterceptor接口 等效 jdk InvocationHandler接口 * intercept() 等效 jdk invoke() * 参数1、参数2、参数3:以invoke一样 * 参数4:methodProxy 方法的代理 * * */ enhancer.setCallback(new MethodInterceptor(){ @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //前 myAspect.before(); //执行目标类的方法 Object obj = method.invoke(userService, args); // * 执行代理类的父类 ,执行目标类 (目标类和代理类 父子关系) methodProxy.invokeSuper(proxy, args); //后 myAspect.after(); return obj; } }); //3.4 创建代理 UserServiceImpl proxService = (UserServiceImpl) enhancer.create(); return proxService; }}
  • AOP联盟为公告Advice定义了org.aopalliance.aop.Advice
  • Spring根据布告Advice在对象类措施的连接点地点,能够分为伍类• 平放通知org.springframework.aop.MethodBeforeAdvice• 在指标措施施行前举办巩固• 前置通告org.springframework.aop.AfterReturningAdvice• 在对象措施实施后实行进步• 环绕公告org.aopalliance.intercept.MethodInterceptor• 在对象措施实行前后推行进步• 卓殊抛出通告org.springframework.aop.ThrowsAdvice• 在形式抛出13分后实施进步• 引导介绍通告 org.springframework.aop.IntroductionInterceptor• 在对象类中增加一些新的不2秘籍和特性

围绕公告,必须手动实施对象措施

try{ //前置通知 //执行目标方法 //后置通知} catch(){ //抛出异常通知}
  • 让spring 创制代理对象,从spring容器中手动的拿走代理对象。
  • 导入jar包:核心:4 1AOP:AOP联盟、spring-aop

图片 9

 

1.4.1 目标类

public interface UserService { public void addUser(); public void updateUser(); public void deleteUser();}

          Hibernate 开发           

1.4.2 切面类

/** * 切面类中确定通知,需要实现不同接口,接口就是规范,从而就确定方法名称。 * * 采用“环绕通知” MethodInterceptor * */public class MyAspect implements MethodInterceptor { @Override public Object invoke(MethodInvocation mi) throws Throwable { System.out.println; //手动执行目标方法 Object obj = mi.proceed(); System.out.println; return obj; }}
 Session session=….;
 Transaction t=session.beginTransaction();
 t.commit();
 t.rollback();

1.4.3 spring配置

<!-- 1 创建目标类 --> <bean ></bean> <!-- 2 创建切面类 --> <bean ></bean> <!-- 3 创建代理类 * 使用工厂bean FactoryBean ,底层调用 getObject() 返回特殊bean * ProxyFactoryBean 用于创建代理工厂bean,生成特殊代理对象 interfaces : 确定接口们 通过<array>可以设置多个值 只有一个值时,value="" target : 确定目标类 interceptorNames : 通知 切面类的名称,类型String[],如果设置一个值 value="" optimize :强制使用cglib <property name="optimize" value="true"></property> 底层机制 如果目标类有接口,采用jdk动态代理 如果没有接口,采用cglib 字节码增强 如果声明 optimize = true ,无论是否有接口,都采用cglib --> <bean > <property name="interfaces" value="com.itheima.b_factory_bean.UserService"></property> <property name="target" ref="userServiceId"></property> <property name="interceptorNames" value="myAspectId"></property> </bean>

 

1.4.4 测试

图片 10

 @Test public void demo01(){ String xmlPath = "com/itheima/b_factory_bean/beans.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext; //获得代理类 UserService userService = (UserService) applicationContext.getBean("proxyServiceId"); userService.addUser(); userService.updateUser(); userService.deleteUser(); }
  • 从spring容器获得指标类,假如安顿aop,spring将自动生成代理。
  • 要明确目的类,aspectj 切入点表明式,导入jar包spring-framework-三.0.2.RELEASE-dependenciesorg.aspectjcom.springsource.org.aspectj.weaver1.6.8.RELEASE

    图片 11

          PlatformTransactionManager 接口API
          DataSourceTransactionManager 首要针对于JdbcTemplate开辟MyBatis开拓;
          HibernateTransactionManasger 主要针对于Hibernate开荒;
          JpaTransactionManager 紧要针对于JPA开辟。
        (2)TransactionDefinition
          它描述的是事情的概念消息,在TransactionDefinition中定义了大量的常量。
    8.1 隔离
        事务的七个特点:ACID原子性、1致性、隔绝性、长久性。
        脏读,不可重复读 虚读。
            ISOLATION_DEFUALT 它应用后端数据库的默许隔开分离等级(spring 中甄选)
            ISOLATION_READ_UNCOMMITTED 不能够化解难题,会发生脏读 不可重复读 虚读
            ISOLATION_READ_COMMITTED 可以解决脏读 会发生不可重复读与虚读。
            ISOLATION_REPEATABLE_READ 能够消除脏读,不可重复读 化解不了虚读
            ISOLATION_SECR-VIALIZABLE 串行化,能够解决所有难题
        对于不现的数据库,它的尾巴部分暗中认可事务隔绝等级不雷同。
            Oracle 数据库它暗中认可的是 read_committed
            Mysql 数据库它暗中认可的是 repeatable_read.
    8.2 超时
        暗许值是-1它使用的是数据库暗中同意的逾期时间。
    8.3 只读
        它的值有三个true/false,假使选取true一般是在select操作时
    8.4 传播
        化解的是三个被事务管理的方式互相调用难题。它与数据库不要紧,是先后内部维护的主题素材。当中:
           PROPAGATION_REQUIRED 私下认可值 八个操作处于同2个事务,假使从前从没职业,新建多个事情;
           PROPAGATION_REQUIRES_NEW多个操作处于不一致的思想政治工作;
           PROPAGATION_NESTED是一种嵌套事务,它是利用 SavePoint 来兑现的。事务回滚时方可回滚到钦命的savepoint,
         注意:它只对DataSourceTransactionManager有作用;
           PROPAGATION_SUPPORTS 辅助当前业务,假使不设有,就不选拔工作;
           PROPAGATION_MANDATORAV4Y 帮助当前职业,借使不存在,抛出特别;
           PROPAGATION_NOT_SUPPORTED 以非事务运维,借使有事情存在,挂起方今事情;
           PROPAGATION_NEVE奇骏 以非事务运维,假如有事情存在,抛出十二分;
    8.5 TransactionStatus
        定义了事情形态音信,在事情运转进程中,获得有个别时间点的情景。
    八.6 注明式事务管理
     (一)事务管理情势
        一. 编码方案 不提议采用,它兼具侵入性。在原本的业务代码基础上来加多事务管理代码。
        二. 注明式事务调整,基于 AOP 对指标进行代理,增加 around 环绕通告。
        这种方案,它不具备侵入性,无需修改原来的事务代码
     (二)基于xml配置声明式事务处理方案
        第①步:在applicationContext.xml文件中增添aop与tx的称呼空间
        第2步:在applicationContext.xml件中布局
        Spring提供的advice是价值观的 spring advice
          一. 扬言事务管理器
          二. 布置公告
             Spring为大家提供了一个ransactionInterceptor来完毕加强对于那么些巩固,大家得以行使spring为大家提供的3个标签
          <tx:advice>来产生操作
          三. 布局切面
             因为使用的是价值观的Spring的Advice,必要选用<aop:advisor>。
     (三)基于Annotation表明式事务管理方案
          可以运用@Transaction来在类或措施上加多注解式事务管理。
            注意:要求在 applicationContext.xml 文件中使用一定于打开注脚事务调控。

1.5.1 spring配置

图片 12

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 1 创建目标类 --> <bean ></bean> <!-- 2 创建切面类 --> <bean ></bean> <!-- 3 aop编程 3.1 导入命名空间 3.2 使用 <aop:config>进行配置 proxy-target- 声明时使用cglib代理 <aop:pointcut> 切入点 ,从目标对象获得具体方法 <aop:advisor> 特殊的切面,只有一个通知 和 一个切入点 advice-ref 通知引用 pointcut-ref 切入点引用 3.3 切入点表达式 execution(* com.itheima.c_spring_aop.*.* 选择方法 返回值任意 包 类名任意 方法名任意 参数任意 --> <aop:config proxy-target-> <aop:pointcut expression="execution(* com.itheima.c_spring_aop.*.*" /> <aop:advisor advice-ref="myAspectId" pointcut-ref="myPointCut"/> </aop:config></beans>

1.5.2 测试

 @Test public void demo01(){ String xmlPath = "com/itheima/c_spring_aop/beans.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext; //获得目标类 UserService userService = (UserService) applicationContext.getBean("userServiceId"); userService.addUser(); userService.updateUser(); userService.deleteUser(); }
  • AspectJ是三个基于Java语言的AOP框架
  • Spring二.0从此新扩大了对AspectJ切点表明式补助
  • @AspectJ 是AspectJ一.5新扩大效益,通过JDK5注解本领,允许直接在Bean类中定义切面新本子Spring框架,提出使用AspectJ格局来支付AOP
  • 首要用途:自定义开荒

壹.execution() 用于描述方法

 语法:execution(修饰符 返回值 包.类.方法名 throws异常) 修饰符,一般省略 public 公共方法 * 任意 返回值,不能省略 void 返回没有值 String 返回值字符串 * 任意 包,[省略] com.itheima.crm 固定包 com.itheima.crm.*.service crm包下面子包任意 (例如:com.itheima.crm.staff.service) com.itheima.crm.. crm包下面的所有子包 com.itheima.crm.*.service.. crm包下面任意子包,固定目录service,service目录任意包 类,[省略] UserServiceImpl 指定类 *Impl 以Impl结尾 User* 以User开头 * 任意 方法名,不能省略 addUser 固定方法 add* 以add开头 *Do 以Do结尾 * 任意  无参  一个整型  两个  参数任意 throws ,可省略,一般不写。综合1 execution(* com.itheima.crm.*.service..*.*综合2 <aop:pointcut expression="execution(* com.itheima.*WithCommit.* || execution(* com.itheima.*Service.*" />

二.within:相称包或子包中的方法

 within(com.itheima.aop..*)

三.this:相配完结接口的代理对象中的方法

 this(com.itheima.aop.user.UserDAO)

4.target:相配落成接口的靶子对象中的方法

 target(com.itheima.aop.user.UserDAO)

5.args:相称参数格式符合规范的主意

 args

陆.bean 对点名的bean全体的章程

 bean('userServiceId')
  • aop缔盟定义公告类型,具备特色接口,必须兑现,从而分明方法名称。
  • aspectj 通告类型,只定义类型名称。已经方法格式。
  • 个数:二种,知道各样,明白第11中学。before:前置通告在章程试行前实行,要是文告抛出万分,阻止方法运营afterReturning:前置通告(应用:常规数量管理)方法平日重临后施行,要是格局中抛出相当,文告不可能试行必须在点子实施后才实行,所以可以得到艺术的重临值。around:环绕通知(应用:十三分精锐,可以做别的职业)方法推行前后分别施行,能够阻止方法的实行必须手动实施对象措施afterThrowing:抛出非常公告(应用:包装格外消息)方法抛出13分后举办,要是艺术未有抛出特别,不或者施行after:最终布告方法施行完结后进行,无论格局中是还是不是出现万分环绕
try{ //前置:before //手动执行目标方法 //后置:afterRetruning} catch(){ //抛出异常 afterThrowing} finally{ //最终 after}

图片 13图片 14图片 15图片 16

  • 五个:aop结盟正式spring aop 完结aspect 标准spring aspect 达成

    图片 17

壹.指标类:接口 实现贰.切面类:编写多少个照管,接纳aspectj 公告名称猖獗三.aop编制程序,将布告应用到对象类4.测试

2.5.1 切面类

/** * 切面类,含有多个通知 */public class MyAspect { public void myBefore(JoinPoint joinPoint){ System.out.println("前置通知 : "   joinPoint.getSignature().getName; } public void myAfterReturning(JoinPoint joinPoint,Object ret){ System.out.println("后置通知 : "   joinPoint.getSignature().getName()   " , -->"   ret); } public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println; //手动执行目标方法 Object obj = joinPoint.proceed(); System.out.println; return obj; } public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ System.out.println("抛出异常通知 : "   e.getMessage; } public void myAfter(JoinPoint joinPoint){ System.out.println; }}

2.5.2 spring配置

<!-- 1 创建目标类 --> <bean ></bean> <!-- 2 创建切面类 --> <bean ></bean> <!-- 3 aop编程 <aop:aspect> 将切面类 声明“切面”,从而获得通知 ref 切面类引用 <aop:pointcut> 声明一个切入点,所有的通知都可以使用。 expression 切入点表达式 id 名称,用于其它通知引用 --> <aop:config> <aop:aspect ref="myAspectId"> <aop:pointcut expression="execution(* com.itheima.d_aspect.a_xml.UserServiceImpl.*" /> <!-- 3.1 前置通知 <aop:before method="" pointcut="" pointcut-ref=""/> method : 通知,及方法名 pointcut :切入点表达式,此表达式只能当前通知使用。 pointcut-ref : 切入点引用,可以与其他通知共享切入点。 通知方法格式:public void myBefore(JoinPoint joinPoint){ 参数1:org.aspectj.lang.JoinPoint 用于描述连接点,获得目标方法名等 例如: <aop:before method="myBefore" pointcut-ref="myPointCut"/> --> <!-- 3.2后置通知 ,目标方法后执行,获得返回值 <aop:after-returning method="" pointcut-ref="" returning=""/> returning 通知方法第二个参数的名称 通知方法格式:public void myAfterReturning(JoinPoint joinPoint,Object ret){ 参数1:连接点描述 参数2:类型Object,参数名 returning="ret" 配置的 例如: <aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" /> --> <!-- 3.3 环绕通知 <aop:around method="" pointcut-ref=""/> 通知方法格式:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ 返回值类型:Object 方法名:任意 参数:org.aspectj.lang.ProceedingJoinPoint 抛出异常 执行目标方法:Object obj = joinPoint.proceed(); 例如: <aop:around method="myAround" pointcut-ref="myPointCut"/> --> <!-- 3.4 抛出异常 <aop:after-throwing method="" pointcut-ref="" throwing=""/> throwing :通知方法的第二个参数名称 通知方法格式:public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ 参数1:连接点描述对象 参数2:获得异常信息,类型Throwable ,参数名由throwing="e" 配置 例如: <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/> --> <!-- 3.5 最终通知 --> <aop:after method="myAfter" pointcut-ref="myPointCut"/> </aop:aspect> </aop:config>

2.6.1 替换bean

<!-- 1 创建目标类 --> <bean ></bean> <!-- 2 创建切面类 --> <bean ></bean>

图片 18图片 19

  • 注意:扫描
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- 1.扫描 注解类 --> <context:component-scan base-package="com.itheima.d_aspect.b_anno"></context:component-scan>

2.6.2 替换aop

  • 无法不开始展览aspectj 自动代理
<!-- 2.确定 aop注解生效 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  • 宣称切面
 <aop:aspect ref="myAspectId">

图片 20

  • 轮换前置通告
<aop:before method="myBefore" pointcut="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*"/>

 //切入点当前有效 @Before("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.* public void myBefore(JoinPoint joinPoint){ System.out.println("前置通知 : "   joinPoint.getSignature().getName; }
  • 轮换 公共切入点
<aop:pointcut expression="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*" />

//声明公共切入点 @Pointcut("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.* private void myPointCut(){ }
  • 轮换前置
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" />

 @AfterReturning(value="myPointCut()" ,returning="ret") public void myAfterReturning(JoinPoint joinPoint,Object ret){ System.out.println("后置通知 : "   joinPoint.getSignature().getName()   " , -->"   ret); }

图片 21

  • 轮换环绕
<aop:around method="myAround" pointcut-ref="myPointCut"/>

@Around(value = "myPointCut public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println; //手动执行目标方法 Object obj = joinPoint.proceed(); System.out.println; return obj; }
  • 轮换抛出极度
<aop:after-throwing method="myAfterThrowing" pointcut="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*" throwing="e"/>

@AfterThrowing(value="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*" ,throwing="e") public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ System.out.println("抛出异常通知 : "   e.getMessage; }

2.6.3 切面类

/** * 切面类,含有多个通知 */@Component@Aspectpublic class MyAspect { //切入点当前有效// @Before("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.* public void myBefore(JoinPoint joinPoint){ System.out.println("前置通知 : "   joinPoint.getSignature().getName; } //声明公共切入点 @Pointcut("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.* private void myPointCut(){ } // @AfterReturning(value="myPointCut()" ,returning="ret") public void myAfterReturning(JoinPoint joinPoint,Object ret){ System.out.println("后置通知 : "   joinPoint.getSignature().getName()   " , -->"   ret); } // @Around(value = "myPointCut public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println; //手动执行目标方法 Object obj = joinPoint.proceed(); System.out.println; return obj; } // @AfterThrowing(value="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*" ,throwing="e") public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ System.out.println("抛出异常通知 : "   e.getMessage; } @After("myPointCut public void myAfter(JoinPoint joinPoint){ System.out.println; }}

2.6.4 spring配置

<!-- 1.扫描 注解类 --> <context:component-scan base-package="com.itheima.d_aspect.b_anno"></context:component-scan> <!-- 2.确定 aop注解生效 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

二.陆.5 aop评释放区救济总会括

@Aspect 声明切面,修饰切面类,从而获得 通知。通知 @Before 前置 @AfterReturning 后置 @Around 环绕 @AfterThrowing 抛出异常 @After 最终切入点 @PointCut ,修饰方法 private void xxx(){} 之后通过“方法名”获得切入点引用
  • spring 提供用于操作JDBC工具类,类似:DBUtils。
  • 依赖 连接池DataSource

3.1.1 创建表

create database ee19_spring_day02;use ee19_spring_day02;create table t_user( id int primary key auto_increment, username varchar, password varchar;insert into t_user(username,password) values('jack','1234');insert into t_user(username,password) values('rose','5678');

3.1.2 导入jar包

图片 22

3.1.3 javabean

package com.itheima.domain;public class User { private Integer id; private String username; private String password;

public static void main(String[] args) { //1 创建数据源 dbcp BasicDataSource dataSource = new BasicDataSource(); // * 基本4项 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/ee19_spring_day02"); dataSource.setUsername; dataSource.setPassword; //2 创建模板 JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); //3 通过api操作 jdbcTemplate.update("insert into t_user(username,password) values;", "tom","998"); }

<!-- 创建数据源 --> <bean > <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/ee19_spring_day02"></property> <property name="username" value="root"></property> <property name="password" value="1234"></property> </bean> <!-- 创建模板 ,需要注入数据源--> <bean > <property name="dataSource" ref="dataSourceId"></property> </bean> <!-- 配置dao --> <bean > <property name="jdbcTemplate" ref="jdbcTemplateId"></property> </bean>

<!-- 创建数据源 c3p0--> <bean > <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day02"></property> <property name="user" value="root"></property> <property name="password" value="1234"></property> </bean>

3.5.1 dao层

图片 23

三.五.二 spring配置文件

 <!-- 配置dao * dao 继承 JdbcDaoSupport,之后只需要注入数据源,底层将自动创建模板 --> <bean > <property name="dataSource" ref="dataSourceId"></property> </bean>

三.伍.3 源码深入分析

图片 24

3.6.1 properties文件

jdbc.driverClass=com.mysql.jdbc.Driverjdbc.jdbcUrl=jdbc:mysql://localhost:3306/ee19_spring_day02jdbc.user=rootjdbc.password=1234

3.6.2 spring配置

<!-- 加载配置文件 "classpath:"前缀表示 src下 在配置文件之后通过 ${key} 获得内容 --> <context:property-placeholder location="classpath:com/itheima/f_properties/jdbcInfo.properties"/> <!-- 创建数据源 c3p0--> <bean > <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> </bean>
  • 事情:一组工作操作ABCD,要么全体打响,要么全体不成功。
  • 特征:ACID原子性:全体1致性:达成隔绝性:并发长久性:结果
  • 隔开难点:脏读:二个作业读到另1个作业未有付诸的多寡不可重复读:三个业务读到另1个事务已交由的数据虚读:二个事情读到另2个事情已提交的数量
  • 隔断等第:read uncommitted:读未提交。存在叁个难题read committed:读已交给。化解脏读,存在1个难题repeatable read:可另行读。消除:脏读、不可重复读,存在三个难题。serializable :串行化。都化解,单事务。

图片 25

  • mysql 事务操作--轻巧
ABCD 一个事务Connection conn = null;try{ //1 获得连接 conn = ...; //2 开启事务 conn.setAutoCommit; A B C D //3 提交事务 conn.commit();} catche(){ //4 回滚事务 conn.rollback();}
  • mysql 事务操作--Savepoint
需求:AB,CD Connection conn = null;Savepoint savepoint = null; //保存点,记录操作的当前位置,之后可以回滚到指定的位置。try{ //1 获得连接 conn = ...; //2 开启事务 conn.setAutoCommit; A B savepoint = conn.setSavepoint(); C D //3 提交事务 conn.commit();} catche(){ if(savepoint != null){ //CD异常 // 回滚到CD之前 conn.rollback(savepoint); // 提交AB conn.commit(); } else{ //AB异常 // 回滚AB conn.rollback(); }}

4.2.1 导入jar包

transaction --> tx

图片 26

四.二.贰 八个拔尖接口

图片 27

  • PlatformTransactionManager 平台作业管理器,spring要管住业务,必须接纳专门的学问管理器实行业务配置时,必须配备事务管理器。
  • TransactionDefinition:事务详细的情况(事务定义、事务属性),spring用于鲜明专门的学业具体详细的情况,举例:隔开分离等级、是还是不是只读、超时时间 等开始展览作业配置时,必须安插详细情况。spring将布署项封装到该对象实例。
  • TransactionStatus:事务状态,spring用于记录当前作业运维情况。例如:是还是不是有保存点,事务是或不是做到。spring底层依照气象实行相应操作。

4.二.3 PlatformTransactionManager 事务管理器

  • 导入jar包:要求时平台业务管理器的达成类

    图片 28

  • 大面积的作业管理器DataSourceTransactionManager ,jdbc开辟时专业管理器,选择JdbcTemplateHibernateTransactionManager,hibernate开荒时工作管理器,整合hibernate

图片 29

  • api详解
TransactionStatus getTransaction(TransactionDefinition definition) ,事务管理器 通过“事务详情”,获得“事务状态”,从而管理事务。void commit(TransactionStatus status) 根据状态提交void rollback(TransactionStatus status) 根据状态回滚

4.2.4 TransactionStatus

图片 30

4.2.5 TransactionDefinition

图片 31

  • 传播行为:在四个业务之间怎样共享专门的学业。
PROPAGATION_REQUIRED , required , 必须  支持当前事务,A如果有事务,B将使用该事务。 如果A没有事务,B将创建一个新的事务。PROPAGATION_SUPPORTS ,supports ,支持 支持当前事务,A如果有事务,B将使用该事务。 如果A没有事务,B将以非事务执行。PROPAGATION_MANDATORY,mandatory ,强制 支持当前事务,A如果有事务,B将使用该事务。 如果A没有事务,B将抛异常。PROPAGATION_REQUIRES_NEW , requires_new ,必须新的 如果A有事务,将A的事务挂起,B创建一个新的事务 如果A没有事务,B创建一个新的事务PROPAGATION_NOT_SUPPORTED ,not_supported ,不支持 如果A有事务,将A的事务挂起,B将以非事务执行 如果A没有事务,B将以非事务执行PROPAGATION_NEVER ,never,从不 如果A有事务,B将抛异常 如果A没有事务,B将以非事务执行PROPAGATION_NESTED ,nested ,嵌套 A和B底层采用保存点机制,形成嵌套事务。

掌握:PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED

4.3.一 搭建碰着

create database ee19_spring_day03;use ee19_spring_day03;create table account( id int primary key auto_increment, username varchar, money int);insert into account(username,money) values('jack','10000');insert into account(username,money) values('rose','10000');
  • 核心:4 1
  • aop : 4 (aop联盟、spring aop、aspectj规范、spring aspect)
  • 数据库:2
  • 驱动:mysql
  • 连接池:c3p0

图片 32

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { @Override public void out(String outer, Integer money) { this.getJdbcTemplate().update("update account set money = money - ? where username = ?", money,outer); } @Override public void in(String inner, Integer money) { this.getJdbcTemplate().update("update account set money = money   ? where username = ?", money,inner); }}

public class AccountServiceImpl implements AccountService { private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void transfer(String outer, String inner, Integer money) { accountDao.out(outer, money); //断电// int i = 1/0; accountDao.in(inner, money); }}

 <!-- 1 datasource --> <bean > <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03"></property> <property name="user" value="root"></property> <property name="password" value="1234"></property> </bean> <!-- 2 dao --> <bean > <property name="dataSource" ref="dataSource"></property> </bean> <!-- 3 service --> <bean > <property name="accountDao" ref="accountDao"></property> </bean>

 @Test public void demo01(){ String xmlPath = "applicationContext.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext; AccountService accountService = (AccountService) applicationContext.getBean("accountService"); accountService.transfer("jack", "rose", 1000); }

四.三.二 手动管理作业

  • spring底层使用 TransactionTemplate 事务模板实行操作。
  • 操作一.service 亟需得到 TransactionTemplate二.spring 配置模板,并流入给service三.模板要求注入事务管理器肆.配备事务管理器:DataSourceTransactionManager ,必要注入DataSource
 //需要spring注入模板 private TransactionTemplate transactionTemplate; public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } @Override public void transfer(final String outer,final String inner,final Integer money) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { accountDao.out(outer, money); //断电// int i = 1/0; accountDao.in(inner, money); } }); }

<!-- 3 service --> <bean > <property name="accountDao" ref="accountDao"></property> <property name="transactionTemplate" ref="transactionTemplate"></property> </bean> <!-- 4 创建模板 --> <bean > <property name="transactionManager" ref="txManager"></property> </bean> <!-- 5 配置事务管理器 ,管理器需要事务,事务从Connection获得,连接从连接池DataSource获得 --> <bean > <property name="dataSource" ref="dataSource"></property> </bean>

4.三.3 工厂bean 生成代理:半机动

  • spring提供 处监护人务的代办工厂bean TransactionProxyFactoryBean1.getBean() 得到代理对象二.spring 布置三个代理
<!-- 4 service 代理对象 4.1 proxyInterfaces 接口 4.2 target 目标类 4.3 transactionManager 事务管理器 4.4 transactionAttributes 事务属性 prop.key :确定哪些方法使用当前事务配置 prop.text:用于配置事务详情 格式:PROPAGATION,ISOLATION,readOnly,-Exception, Exception 传播行为 隔离级别 是否只读 异常回滚 异常提交 例如: <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop> 默认传播行为,和隔离级别 <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop> 只读 <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT, java.lang.ArithmeticException</prop> 有异常扔提交 --> <bean > <property name="proxyInterfaces" value="com.itheima.service.AccountService"></property> <property name="target" ref="accountService"></property> <property name="transactionManager" ref="txManager"></property> <property name="transactionAttributes"> <props> <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop> </props> </property> </bean> <!-- 5 事务管理器 --> <bean > <property name="dataSource" ref="dataSource"></property> </bean> 

图片 33

肆.3.四 AOP 配置基于xml

  • 在spring xml 配置aop 自动生成代理,举办业务的管住1.安顿管理器二.安插事务详细的情况三.安插aop
<!-- 4 事务管理 --> <!-- 4.1 事务管理器 --> <bean > <property name="dataSource" ref="dataSource"></property> </bean> <!-- 4.2 事务详情 , 在aop筛选基础上,对ABC三个确定使用什么样的事务。例如:AC读写、B只读 等 <tx:attributes> 用于配置事务详情 <tx:method name=""/> 详情具体配置 propagation 传播行为 , REQUIRED:必须;REQUIRES_NEW:必须是新的 isolation 隔离级别 --> <tx:advice transaction-manager="txManager"> <tx:attributes> <tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/> </tx:attributes> </tx:advice> <!-- 4.3 AOP编程,目标类有ABCD,切入点表达式 确定增强的连接器,从而获得切入点:ABC --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service..*.*"/> </aop:config>

肆.三.伍 AOP配置基于申明

  • 1.配备事务管理器,将并工作管理器交予spring
  • 二.在指标类或指标措施增加注脚就能够 @Transactional
<!-- 4 事务管理 --> <!-- 4.1 事务管理器 --> <bean > <property name="dataSource" ref="dataSource"></property> </bean> <!-- 4.2 将管理器交予spring * transaction-manager 配置事务管理器 * proxy-target-class true : 底层强制使用cglib 代理 --> <tx:annotation-driven transaction-manager="txManager"/>

@Transactionalpublic class AccountServiceImpl implements AccountService {

图片 34

@Transactional(propagation=Propagation.REQUIRED , isolation = Isolation.DEFAULT)public class AccountServiceImpl implements AccountService {
  • 导入jar包基本 :4 1测试:spring-test...jar

一.让Junit通告spring加载配置文件二.让spring容器自动进行注入

  • 修改测试类
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations="classpath:applicationContext.xml")public class TestApp { @Autowired //与junit整合,不需要在spring xml配置扫描 private AccountService accountService; @Test public void demo01(){// String xmlPath = "applicationContext.xml";// ApplicationContext applicationContext = new ClassPathXmlApplicationContext;// AccountService accountService = (AccountService) applicationContext.getBean("accountService"); accountService.transfer("jack", "rose", 1000); }}

spring-web.xml

图片 35

servlet --> init(ServletConfig) --> <load-on-startup>2filter --> init(FilterConfig) --> web.xml注册过滤器自动调用初始化listener --> ServletContextListener --> servletContext对象监听【】spring提供监听器 ContextLoaderListener --> web.xml <listener><listener-class>.... 如果只配置监听器,默认加载xml位置:/WEB-INF/applicationContext.xml

图片 36

6.3规定布置文件地点,通过系统开头化参数

ServletContext 起始化参数 web.xml

 <context-param> <param-name>contextConfigLocation <param-value>classpath:applicationContext.xml

 <!-- 确定配置文件位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- 配置spring 监听器,加载xml配置文件 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>

// 从application作用域(ServletContext)获得spring容器//方式1: 手动从作用域获取ApplicationContext applicationContext = (ApplicationContext) this.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);//方式2:通过工具获取ApplicationContext apppApplicationContext2 =WebApplicationContextUtils.getWebApplicationContext(this.getServletContext; 

本文由必发88官网发布,转载请注明来源:Spring知识总括