graph LR
spring内容 --> spring框架概述
spring内容 --> ioc容器
spring内容 --> aop
spring内容 --> JdbcTemplate
spring内容 --> 事务管理
spring内容 --> spring5新特性
一.是什么
1.简介
<1>.spring是一个轻量级ioc和aop的容器框架
<2>.历史:
i.2002年,首次推出了spring的前身,interface21框架
ii.2004年3月24号,spring发布了1.0版本
iii.创始人是Rod Johnson
<3>.SSH:Struck2+Spring+Hibernate(自动化)
<4>.SSM:springboot+spring+mybatis(半自动化,支持个性定制sql语句)
2.spring组成
二.为什么用
解决企业应用开发的复杂性,简化servlet
1.优点:
<1>spring是一个开源免费的框架(容器)
<2>spring是一个轻量级,非入侵式的框架
<3>ioc,aop
<4>支持事务的处理
<5>支持对框架整合的支持
2.弊端
发展了这么久,配置十分多
3.扩展
<1>现代化的java开发,就是基于spring的开发
<2>spring和springmvc是学习springboot快速开发的前提
4.特点
<1>基于ioc思想,方便解耦,简化开发
<2>aop编程的开发
<3>方便程序的测试
<4>方便集成各种优秀框架
<5>方便进行事务的操作,
<6>降低API的开发难度(如封装了jdbc等)
三.spring快速入门
1.获得spring
官方下载
github下载
<1>
<2>
<3>
<4>
<5>
<6>下载的spring5在本地的位置
2.spring快速入门
<1>创建一个普通java工程
<2>导入核心依赖 (需要4个jar包)
I.spring依赖(入门案例需要5个jar包)
II.logging包
III.把依赖放入java工程内
IV.编写普通类,普通类中编写普通方法
V.使用spring创建对象
spring中创建对象方式:xml,注解,零配置
i.xml方式
①在xml 配置文件中创建bean标签来配置创建对象
②编写测试类,并导入junit包
③测试
四.ioc
graph LR
ioc容器 --> ioc底层原理
ioc底层原理 --> xml解析
ioc底层原理 --> 工厂模式
ioc底层原理 --> 反射
ioc容器 --> ioc两个接口
ioc两个接口--> BeanFactory
ioc两个接口 --> ApplicationContext
ioc容器 --> ioc操作bean管理
ioc操作bean管理 --> 基于xml
ioc操作bean管理 --> 基于注解
ioc操作bean管理 --> 基于JavaConfig
0.控制反转(获得依赖对象的方式反转了)
控制反转是一种通过描述(xml或注解)并通过第三方去生产或获取特定对象的方式,再spring中实现控制反转的是ioc容器,实现方法是依赖注入(DI)
控制:传统应用程序的对象是由程序本身控制创建的,spring是由spring创建对象
反转:程序本身不创建对象,变成被动的接受对象
依赖注入:利用set方式注入
总结控制反转:把创建对象和对象之间的调用的过程交给spring进行管理
1.ioc——底层原理
<1>ioc理论推导:(service层调用dao层为例)
I.原始方式创建对象并调用
i.图解
ii.代码实现
①.创建maven项目,并创建父子工程模块,父项目pom文件导入jar包依赖
②.创建UserDao接口,写方法
③.创建UserDaoImpl实现类
④.创建UserService业务接口,写方法
⑤.创建UserServiceImpl业务实现类,通过new对象方式调用Dao层对象,实现方法(核心)
⑥写测试类,调用service层业务
⑦.功能增强——后台加一个Dao
⑧.功能增强——service层修改
⑨.功能增强——测试
⑩.结论
功能增强了,但是增加了类的同时(也就是用户需求改变的时候),改变了原有的代码,会破环程序的完整性
II.工厂模式实现对象的创建和调用
降低了service层和dao层的耦合度
i.图解
ii.代码实现
参考原始方式
III.ioc方式实现对象的创建和调用
需要用到xml解析,工厂模式和反射完成最大程度的解耦合
i.图解
当需要功能增强的时候,不需要修改sercive层代码,只需要修改配置文件
ii.代码实现
参考操作bean管理的注入属性——xml方式注入其他类型
<2>ioc思想与ioc容器
I.概念
ioc思想必须要基于ioc容器完成,而ioc容器本质上就是对象工厂,在工厂中读取配置文件,通过反射创建对象
II.两个接口
使用工厂就需要实例化工厂,spring提供了实现ioc容器的两种方式:(两个重要的接口)
i.BeanFactory
ii.ApplicationContext
2.ioc——接口
BeanFactory 与ApplicationContext 两个接口作用相似,都能加载配置文件,并通过工厂创建对象
<1>.BeanFactory
I.是什么
spring内置的接口,一般是内部使用,开发中一般不使用
II.特点
它在加载配置文件bean.xml的时候不会创建对象,就算写了配置文件也不会因为配置文件创建出来对象;只有使用getBean()的时候才会创建对象
<2>.ApplicationContext
I.是什么
是BeanFactory的子接口,提供了更多功能,一般由开发人员使用
II.特点
它在加载配置文件的时候就已经创建对象了,只要配置文件中通过bean标签配置了对象,加载配置文件的时候都会创建出来相应的对象
<3>两个接口对比
实际中,用哪个接口的方式更好?
单独比较,BeanFactory更好,因为用的时候才创建对象可以节约资源;
但是我们用spring框架一般要整合web项目 ,比如要用到tomcat服务器,所以在项目启动时把这些耗时耗资源的操作进行处理更好;
总结,实际开发中用ApplicationContext更好,可以在服务器启动时就加载配置文件,让创建对象的过程在启动服务器时完成,而不是操作中完成,这样我们就可以直接把对象拿来就用
<4>ApplicationContext接口的重要实现类对比
I.查看接口的层级结构:control+h
II.两个实现类对比
xml配置文件的放置路径:
ClassPathXmlApplicationContext:bean.xml的路径是类路径,也就是src下;
FileSystemXmlApplicationContext:bean.xml的路径是本地路径
<5>BeanFactory接口的重要实现类对比
I.查看接口的层级结构:control+h
3.ioc——具体操作(Bean管理操作)
<1>Bean管理
指的是两个操作:
I.spring创建对象
II.spring注入属性
<2>实现bean管理的三种方式
I.xml实现bean管理
i.基于xml创建对象
在spring配置文件中添加bean标签,在标签中添加属性就可以完成对象的创建;在spring中创建对象默认执行无参构造的方法
ii.基于xml注入属性(spring支持以下方式注入属性)
注入属性的方式:DI依赖注入(注入属性)
它是ioc容器中的一种具体实现
①set()方法注入属性
1)创建类,写属性和对应的set()方法
2)在spring配置文件中配置对象的创建和属性的注入
3)测试
②通过有参构造方式注入属性
1)创建类,定义属性和对应的有参构造方法
2)spring配置文件中写配置
3)测试
③p标签属性注入
简化基于xml方式的set注入
iii.xml方式注入其他类型属性
①字面量:属性的值
1)null值
对属性的值进行一个空值的注入
2)属性的值包含特殊符号
②xml方式注入属性——引入外部bean
举例:web项目一般按三层架构写,我们以service层和dao层为例,service层调用dao层,这就是引入外部bean
1)原始方式实现引入外部bean
参考ioc理论推导
2)ioc方式实现
基于xml方式用set()方式实现
1~.service层和dao层编写
2~.xml配置文件编写
3~.测试
③xml方式注入属性——内部bean和级联赋值
内部bean和级联赋值理解:数据库表的关系有一对一一对多,和这个有关系
1)一对多关系的实现
1~.内部bean
2~.级联赋值(通过外部bean)
1>.编写两个实体类
2>.xml中注册bean
3~.第二种级联赋值的写法
④xml方式注入属性——注入集合属性
1).注入数组,List,Map属性
参考③xml方式注入属性——内部bean和级联赋值
2)补充:提取集合类型属性作为公共部分
iv.ioc的xml方式实现-Demo练习
①写类,new对象
②实例化容器
③总结:
xml方式可以让我们不用再程序中改动,只需要再xml配置文件中进行修改
④升级
v.bean讲解
①spring里面有两种类型的bean
1)我们创建的普通bean——普通bean
特点:在xml配置文件中配置的bean,定义的class类型,返回的类型就是定义的类型
实现:
2)spring内置的bean——工厂bean
FactoryBean(工厂bean)
特点:xml配置文件中配置的bean,定义的class类型,返回的类型不一定是定义的类型
实现:创建类,作为工厂bean,实现接口FactoryBean;
实现接口的方法,在实现的方法中定义返回的bean类型
②bean的作用域(bean scopes)
面试题回答:
spring框架里的ioc容器是可以非常方便的帮助我们去管理应用里面的bean对象的一个实例的,我只需要按照spring里面提供的xml或者注解的方式去告诉ioc容器,哪些bean需要被ioc容器管理就可以了,其次,既然是bean对象的实例管理,那么意味着这些实例是存在生命周期的,也就是一个所谓的作用域,理论上说,常规的生命周期只有两种,第一种是单例(singleton),意味着在整个spring容器中只存在一个bean实例,第二个是原型(prototype),意味着每次从ioc容器去获取指定bean实例的时候,都会返回一个新的实例对象,但是在基于spring框架的web应用里面,增加了一个会话维度来控制bean的生命周期这样一个功能,它主要有三个选项,第一个是request,它会针对每一次http请求创建一个新的bean ,第二个是session,同一个session共享共享同一个bean实例,不同的session产生不同的bean实例,最后一个是globalsession,它是针对全局session的维度共享同一个bean的实例
以上就是我对这个问题的理解
当我们通过xml配置文件,注册bean,测试类得到注册的bean对象;这个过程对于spring,在创建bean实例的时候,这个实例可以是单例或多例对象;设置它是单实例还是多实例就是bean的作用域;
通过多次获取对象并比较对象的地址值判断是否是单实例或多实例
1).单例模式
spring默认机制就是单例,可以不写出来,全局共享一个bean注册的对象;
这种方式在并发情况下可能会有延迟或者数据不一致的情况,适用于单线程
2).原型模式
每次从容器中get的时候,都会产生一个新对象;
每一个bean注册的都是单独的对象;
这种方式浪费资源;适用于多线程
3)singleton和prototype的区别
bean标签中如果scope属性设置为singleton或者默认不设置,spring会在加载xml配置文件时创建单例对象;
如果scope属性设置为prototype,spring不会在加载xml配置文件时创建多例对象,会在使用getBean()时创建多例对象
4).其余的request,session,application
这几个只有在web开发下,spring的applicationContext中使用才可以
③bean的生命周期
面试回答:
bean的生命周期大致可以分为五个阶段,分别是创建前准备,创建实例化,依赖注入,容器缓存和销毁实例这样一些阶段,下面我对每个阶段做一个详细的说明,
第一个阶段,创建前准备,这个阶段的作用是bean在开始加载之前,要从上下文和配置中去解析和查找bean有关的扩展实现,比如像init-method,容器在初始化bean的时候会调用的方法,destory-method,容器在销毁bean的时候调用的方法,这些类或者配置是spring提供给开发者用来去实现bean加载过程中的一些扩展,在很多和spring集成的中间件也比较常见,比如像dubbo这样一些中间件;
第二个阶段,是创建实例阶段,这个阶段的主要作用,是通过反射去创建bean的实例对象,并且会扫描和解析bean声明的一些属性;
第三个阶段是依赖注入阶段,如果被实例的bean存在依赖其他bean对象的情况,就需要对这些依赖的bean,进行对象注入,比如常见的@autowired以及setter注入等这样一些配置形式,同时在这个阶段,会触发一些扩展的调用,比如说常见的扩展类BeanPostProcessors,用来实现bean初始化前后的扩展回调;
第四个阶段是容器缓存阶段,这个阶段的作用是把bean保存到容器中以及spring的缓存中,这个阶段的bean就可以直接拿来使用了,这个阶段涉及到常见操作像init-method,这个属性配置的一些方法在这个阶段会被调用;
第五个阶段是销毁实例阶段,当spring的应用上下文被关闭的时候,那么这个上下文中所有的bean会被销毁,如果存在bean配置了destory-method属性的方法,在这个阶段会被调用;
以上就是我的全部理解
1)生命周期
对象从创建到销毁的过程,这里指的就是bean对象的创建到销毁的过程
2)bean的生命周期
通过五个步骤完成bean从创建到销毁的过程
3)代码实现
④bean的自动装配
1)自动装配介绍
前面的基于xml方式注入属性,包括使用value,ref(外部bean)等这些都是手动装配;自动装配 就是不需要我们手动注入属性,spring会自动完成属性值的注入;
我们可以指定自动装配的规则,属性名称或属性类型,然后spring自动匹配属性值进行注入
2)代码实现
spring中有三种装配的方式:
在xml中显示配置;
在java中显示配置;
隐式的自动装配(重点,掌握)
1>.环境搭建
三个实体类(JavaBean)(一个人有两个宠物)
2>.注册bean,把实体类配到容器里
3>.测试
4>.ByName的自动装配(id必须一致才能找到)
5>.ByType的自动装配(bean的类型class必须全局唯一,此时id可省略)
3).注解实现自动装配
1>.导入约束(context约束)以及约束的支持
2>.配置注解的支持 (开启注解支持)
3>.xml配置
4>.使用@Atuowired
根据属性类型自动装配
不需要提供set方法,因为注解是用反射做的;最常用的,因为一般用单例就够了
5>@Qualifier
根据属性名称自动装配
如果@Atuowired 自动装配环境复杂,这一个注解无法完成注入的时候,就可以使用@Qualifier(value=“xxx”)配合@Atuowired使用 ,指定唯一的bean对象注入,也就是说spring容器通过id和class找到的出现多个时,就需要用这个注解
6>@Resource(name="xxx")
@Atuowired 和@Qualifier是spring的注解;
@Resource是java原生的注解,相当于@Atuowired 和@Qualifier的组合注解;只要容器中的id和class都找不到才会报错
7>@Atuowired和@Resource区别
相同:都是自动装配;都可以放在属性字段上
不同:Atuowired是通过byName或byType方式实现的,而且要求对象存在,否则空指针,虽然可以通过@Nullable设置字段为空时不报错,但还是解决不掉根本的问题;Resource是默认通过byName实现的,如果找不到名字,通过byType实现,如果两个都找不到就报错
vi.spring的xml配置标签解析
①alias别名,基本不用
②import
团队开发使用,可以将多个配置文件,合并导入为1个;比如三个不同的人负责不同类的开发,不同的类需要注册在不同的bean中,可以利用import将所有人的beans.xml合并为一个,使用的时候使用总配置applicationContext.xml就可以
③beans中bean的配置
④context(引入外部属性文件)
以引入数据库配置文件为例,完成引入外部属性文件并配置连接池属性
1).导入druid依赖
2).编写外部属性文件
3).引入context约束以及命名空间,在xml中取proerties的值
II注解方式实现bean管理
i.为什么用
实际开发中,并不会把简单的bean放在配置文件中
ii.怎么用
①注解创建对象
spring中针对bean管理的创建对象提供以下注解
@Component
@Service
@Controller
@repository
②注解注入属性
③注解实现bean管理代码实现
1).spring4之后,使用注解开发的前提必须要保证导入了aop的包
2).使用注解需要导入context约束,开启注解的支持 (annotation-config是注解驱动的支持)
3).context标签的其他用法
4).component-scan(包扫描)
通过扫描包的方式实现bean注册到ico容器
1~.属性有值的情况
2~.属性没值需要DI注入的情况
3~.组件扫描配置
4~.总结
属性简单的时候用注解,复杂的就用xml配置文件实现注入
5~. @component的衍生注解
web开发中,会按照MVC三层架构分层,@component和衍生的三个注解都是组件的意思,都会把当前类注册到spring容器,都表示被这几个注解标志的类交给了ioc容器托管并且装配bean
Dao层:@Repository
Service层: @Service
Controller层:@Controller
作用域:@scope("")单例/多例
④注解实现自动装配
参考bean的自动装配
III.xml配置和注解配置总结
i.
xml的注册bean被@Component代替了;
xml的注入值被@Value代替了;
xml作用域被@Scope代替了;
ii.
所以注解直接在一个类上就能把他变成bean,但是只能在当前类下使用,别的类不能引用;xml更万能,维护方便;
iii.
实际开发中,两者配合使用,xml完成管理bean,注解完成属性的注入
IV.零配置JavaConfig(新特性)
i.是什么
完全不用配置文件,零配置实现ioc;
直接用java的配置类取代spring的xml配置文件(下图是官网的)(实际上就是使用注解)
ii.为什么用
JavaConfig一开始是spring的一个子项目,后来在spring4之后被推荐使用,成为核心功能,因为她更灵活
iii.怎么用
①.编写Javabean(普通类),准备将其注册到spring容器中
②.编写java配置类
1).配置类详解
2).configuration的底层实现
③.测试
④.多个配置类情况(对应xml配置中有多个bean的情况)
4.谈谈对ioc的工作流程的理解
(ioc是什么)ioc也叫控制反转,它的核心思想是把对象的管理权限交给了容器,应用程序如果需要使用某个对象的实例,直接从ioc容器中获取就可以了,这种设计的好处在于降低了程序里面对象与对象之间的耦合度,使得整个程序的整个体系结构变得更加灵活;(spring中如何声明bean)spring里面提供了很多方式去声明一个bean,比如说在xml配置文件中通过bean的标签或者@service注解或者通过@configuration配置类里面用@bean注解去声明,spring在启动的时候会解析这些bean,然后保存到ioc容器中;(工作流程)spring ioc的工作流程大致可以分为两个阶段,第一个阶段是ioc容器的初始化阶段,这个阶段主要是根据程序里面定义的xml或者注解等bean的声明方式,通过解析和加载后生成beanDefinition,然后注册到ioc容器里面,通过注解或xml声明的bean,都会解析得到一个BeanDefinition实体,这个实体里面会包含bean的一些定义和基本的一些属性,最后把这个BeanDenfiniton保存到一个map集合里面,从而去完成ioc的一个初始化,ioc容器的作用,就是对注册的bean的定义信息进行处理和维护,它是ioc容器控制反转的一个核心,第二个阶段是完成bean的初始化和依赖注入,这个阶段会做两个事情,第一个是通过反射把没有设置lazy-init属性的单例bean进行初始化,,第二步是完成bean的依赖注入,最后一个阶段就是bean的一个使用,通常我们会通过@atuowired这样一个注解或者通过beanFactory.getbean()从ioc容器中去获取一个指定bean的实例,另外针对设置了lazy-init属性以及非单例bean的一个实例化,实在每一次获取bean对象的时候,调用bean的初始化方法来完成实例化的,并且ioc容器不会去管理这些bean。
以上就是我对这个问题的全部理解
五.aop
0.aop概述
<1>面向切面
不修改源代码的前提下进行功能的增强
<2>图解
1.代理模式
代理模式是springAop的底层
代理模式分类:
静态代理
动态代理
代理模式例子理解:租房
<1>.静态代理
好处:公共业务交给代理实现了分工明确,当公共业务扩展的时候方便集中管理
缺点:每一个真实的角色都需要一个代理角色,代码量翻倍
实例1:
I.写接口
II.写真实角色
III.写代理角色
IV.客户端访问代理角色
实例2:
<2>.动态代理模式
动态代理的代理类是自动生成的,不是我们写好的
好处:包含了静态代理的好处,动态代理本身的好处是一个动态代理类可以代理多个类,只要实现了同一个接口就可
动态代理分为三大类:
基于接口的动态代理:JDK实现动态代理
基于类的动态代理:cgib实现动态代理
java字节码实现动态代理:javasist(他是放在JBoss的服务上,上面那两个是放在tomcat上)
I.JDK实现动态代理
i.两个重要的类和接口(api)
proxy,invocationhandler
ii.代码实现
ii.抽取工具类
把处理程序类抽取出来,当成一个万能的工具类
2.aop术语
<1>连接点
<2>切入点
切入点表达式作用:知道对哪个类的哪个方法进行增强
execution()
<3>通知(增强)
<4>切面
<5>图解
3.aop在spring中的作用
提供声明式事务,允许用户自定义切面;
我们需要关注的是横切关注点,如日志,安全,缓存,事务等等
4.aop代码实现
<1>AspectJ
spring框架基于AspectJ实现aop操作;
AspectJ不是spring框架的一部分,是一个独立的AOP框架,一般会把AspectJ框架和spring框架一起使用实现aop的操作
<2>基于AspectJ实现spring的aop操作
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
I.方式一( 使用原生的spring API接口,实现接口 )
i.编写业务层代码
ii.编写log,对业务实现功能增强
iii.把类都注册到xml中(注册bean) ,并且配置aop
iv.spring测试
II.方式二(自定义类/xml的方式实现aop)
i.编写切面类
ii.xml配置
iii.测试
III.方式三(注解实现aop,实际开发用这个)
i.注册bean
ii.编写注解类代替xml中配置
iii.抽取相同切入点
iv.对多个增强类设置优先级
当有多个增强类对同一个方法进行增强,我们可以设置增强类的优先级
实现:在增强类上添加注解@Order(数字类型值),数字类型值越小,优先级越高
5.谈谈对aop的理解
理论:
springaop把jdk动态代理的细节和控制进行了封装,用到了很多概念,包括连接点,切入点,切面,通知 ,aop的目的就是为了在业务上的功能进行解耦;
每一个系统都是由不同的组件组成的,每个组件负责一些特定的功能,有一些组件是和业务无关的,比如日志,事务,权限等核心业务组件,这些核心业务组件经常融入到具体的业务逻辑中,如果我们给给个业务逻辑都添加这样的代码,代码的重复度太高;
比如项目有有100个方法以及写好了,业务逻辑也都正常,测试也都通过了 ,如果这个时候领导说需要在方法上添加一个日志处理,这时候就能用到aop的方式实现,我们可以把这些公共的代码逻辑抽取出来做成一个切面,然后注入到目标对象(也就是具体业务)中,aop就是基于这样的思想实现的,通过动态代理的方式,将需要注入切面的对象进行代理,需要调用的时候,把公共的部分直接添加进去,这样就能做到不修改源代码的情况下,在原来的业务逻辑下做一些功能的增强。
实践:
声明式事务的一个具体的处理逻辑给面试官描述清楚,如使用aop实现一个全局的异常处理;
通用异常处理,比如说代码从dao层抛出异常,不做处理继续抛给service层,然后抛给controller层,再抛给框架,再抛给JVM,如果jvm不处理就抛给了客户,显示再浏览器,因为我们要把代码交给jvm执行,所以没法通过jvm进行异常的处理,所以再框架层面做通用异常处理;由于spring框架有一个重要的思想aop(面向切面编程),所以springmvc就用了aop思想做了通用异常处理,实现过程是,先写了一个自定义的异常处理类,继承了RuntimeException类,重写了里面的一些方法,然后编写通用异常处理类来让自定义的异常处理类生效,springmvc提供了注解@ControllerAdvice做一个统一异常的捕获,并且用另一个注解@ExceptionHandle(自定义异常处理类.class)配合@ControllerAdvice使用,再然后还需要对异常结果做一个处理,目的是为了把返回的数据和状态码封装成一个对象一并返回,所以在编写一个异常结果处理类,继续做优化的话,就是规范异常的提示信息,所以还需要使用到异常提示信息的处理类,通过枚举的方式规范异常的提示信息,最后controller层方法的返回值使用ResponseEntity<实体类>,这样后台返回的数据就会把异常提示信息和状态码同时返回给前台
六.JdbcTemplate模板
1.是什么
spring框架对JDBC部分进行了封装,更容易对数据库表进行crud的操作,封装后的模块就是JdbcTemplate
2.怎么用
<1>导入依赖
。。。
七.spring事务
1.是什么
2.怎么用
<1>编程式事务
通过自己写的代码实现事务的管理,包括事务的开启,提交,关闭,回滚这些操作,手动管理这些操作太麻烦
<2>声明式事务
aop的具体实现
I.xml中配置
II.注解配置
配置类上添加@EnabletranscationManagent开启注解事务,在方法上添加@Transcational实现事务拦截
i.spring的事务是如何配置的
主要是看声明式事务的配置,两种方式,
xml配置文件的方式,配置事务管理器,用tx-advice属性配置定义,配置定义里面主要配置事务的隔离级别,事务的传播特性,事务的回滚,通过aop-config配置切面切入点 ;
注解的方式,配置类上添加@EnabletranscationManagent开启注解事务,在类或者方法上添加@Transcational实现事务的管理
ii. @Transactional注解的属性
` (1)timeout:事务提交时间设置 事务需要在一定时间内进行提交,如果不提交进行回滚默认值为 -1 ,-1是永不超时,设置时间以秒单位进行计算
(2)readonly:是否只读是否只能查询,读操作:查询;写操作:添加 修改 删除 默认值为false,表示可以查询,可以添加修改删除操作设置readOnly值是true之后,只能查询
(3)rollBackFor:回滚设置出现哪些异常进行事务回滚默认为空
(4)noRollBackFor:不回滚设置出现哪些异常不进行事务回滚默认为空
(5)isolation:设置事务隔离级别 mysql默认隔离级别 repeatable read
(6)propagation:设置事务传播行为 概念: 多事务方法之间调用过程中,事务是如何使用的 事务方法: 改变数据库表数据的方法,添加修改删除
例如: 添加方法里面调用修改方法,这个时候的事务如何使用,成为事务的传播行为 spring提供多种事务传播行为(七种)
@Service @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
public class UserService {
`
3.spring事务的实现方式原理
aop的具体实现,在具体的方法上加上@Transcational 这个注解就可以,当添加了这个注解,spring会基于这个类,用jdk或cglib的方式生成一个代理对象作为bean,当调用这个代理对象的方法的时候,如果有事务,会先把事务的自动提交关闭,然后执行业务的具体逻辑,如果业务逻辑执行没有异常,spring框架会把事务会直接提交,如果有异常,spirng框架会进行回滚,用户也可以选择对哪些异常进行回滚
4.spring的事务传播行为有哪些
面试回答:
对于这个问题,需要从几个方面去回答,首先呢,所谓的事务传播行为,就是说多个声明的事务的方法相互调用的时候, 这个事务应该如何去传递,比如说methodA()调用methodB(),这两个方法都开启了事务,那methodB()开启的是一个新的事务,还是继续在methodA()这个事务里去执行,就取决于事务的传播行为;
在spring里面定义了7种事务传播行为,
第一种是required,它是spring默认的事务传播行为,也就是说如果当前存在事务,就加入到这个事务里面去执行,如果不存在事务就新建一个事务;
第二个是required_new,他不管是否存在事务,新老事务之间是相互独立的,外部事物抛出异常并不会影响内部事务的一个正常提交;
第三个是nested,如果当前存在事务,就嵌套在当前事务中去执行,如果当前没有事务,就新建一个事务,类似于required_new的传播行为;
第四个是supports,表示支持当前的事务,如果当前不存在事务,就以非事务的方式去执行;
第五个是not_supports,表示以非事务的方式来运行,如果当前存在事务,就需要把当前的事务挂起来;
第六个是mandatory,它是一个强制的事务执行,就是说如果当前不存在事务,就抛出一个异常;
第七个是never,是以非事务的方式了来执行,如果当前存在事务则抛出异常;
spring里面的事务传播级别,一般是不需要去定义的,默认就是一个required,除非是在嵌套的事务的情况下,才需要去处理;
以上就是我对这个问题的理解
spring中propegation的7种事务配置
5.spring的事务什么时候会失效
bean对象没有被spring容器进行管理
方法的访问修饰符不是public
数据源没有配置事务管理器
数据库不支持事务
异常被捕获
异常类型错误或配置错误
八.spring5新特性
spirng5基于JDK8,兼容JDK9
1.spring5整合日志框架
<1>.介绍
spring5.0框架自带了通用的日志封装,同时也可以整个第三方的日志框架 ,如log4j
I.spring5移除了log4jConfigListener,所以本身不支持log4j,官方建议使用log4j2 ,如果想使用log4j,需要把spring降到4版本
II.spring框架整合log4j2
<2>.代码实现
I.导入依赖
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
II.创建名字为log4j2.xml的配置文件
III.手动设置日志输出并测试
2.@Nullable注解和函数式注册对象
<1>@Nullable注解
spring5核心容器支持@Nullable注解
I.为什么用
空指针异常的问题
II.怎么用
用在方法上:方法返回值可以为空
用在属性上:属性可以为空
用在参数上个:参数值可以为空
III.参考bean的自动装配
<2>函数式风格注册对象并交给spring管理
I.是什么
spring5核心容器支持函数式注册对象,由于spring5基于JDK8,所以同样支持lambda表达式;
支持的两个对象:
GenericApplicationContext
AnnotationConfigApplicationContext
II.为什么用
spring5创建对象的过程都交给了ioc容器,我们通过注册bean或者注解的方式或者javaConfig的方式实现,但是当我们想要想最原始的方式,自己new对象的时候,就需要我们把对象注册到ioc容器中,这样spring才能管理自己new的对象;
3.测试方面的改进(Junit5单元测试框架)
<1>.为什么用
spring5增加了多个注解来支持对Junit5的一个整合;
原先在测试类中需要在标注@Test的注解的方法内,先加载配置文件,在getBean()获取bean对象;整和junit可以把加载配置文件以及getBean()的内容用注解方式实现
<2>.spring分别整合Junit4和Junit5进行对比
I.整合junit4
原先在测试类中需要在标注@Test的注解的方法内,先加载配置文件,在getBean()获取bean对象;
i.导入spirng5和Junit4依赖
ii.创建测试类,使用注解方式完成加载配置文件,并通过@Autowired代替getBean()
II.整合Junit5
i.导入spirng5和Junit5依赖