Spring Framework
2023-12-27 15:04:41 33 举报
AI智能生成
Spring Framework
作者其他创作
大纲/内容
spring Bean
配置方式
XML配置
注入bean的方式
Setter注入
构造方法注入,①通过index设置参数的位置;②通过type设置参数类型;
静态工厂注入
实例注入
注解配置
Java配置
作用域
singleton : bean在每个Spring ioc 容器中只有一个实例。
prototype:一个bean的定义可以有多个实例。
request:每次http请求都会创建一个bean
session:在一个HTTP Session中
global-session:在一个全局的HTTP Session中,仅在基于portlet的web应用中才有意义
生命周期
内部Bean
内部Bean通常是匿名的,所有scope是protoType
注入一个java集合
直接将一个集合注册为一个Bean
自动装载Bean
no
默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean
ByName
ByType
constructor
利用构造函数进行装配,并且构造函数的参数通过byType进行装配。
autodectect
自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。
@Autowired
容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会
在IoC容器自动查找需要的bean,并装配给该对象的属性。
在IoC容器自动查找需要的bean,并装配给该对象的属性。
1.查找对应类型的Bean
2.通过类型查找有多个,则根据名字查找
3.如果都找不到抛出异常
解决办法:required=false
注解
@Component
@Controller
@Service
@Repository
@Component 注解的特化,它将 DAO 导入 IoC 容器,并使未经检查的异常有
资格转换为 Spring DataAccessException。
资格转换为 Spring DataAccessException。
@Autowired
默认类型注入,再名称
@Resource
默认名称注入,再类型
@Qualifier
创建多个相同类型的 bean 并希望仅使用属性装配其中一个 bean 时,您可以使用@Qualifier 注解和 @Autowired 通过指定应该装配哪个确切的 bean 来消除歧义。
事务
事务方式
申明式事务
简单,灵活性相对差
编程事事务
难度大,灵活性好
事务传播行为
PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
PROPAGATION_REQUIRES_NEW(新建事务):创建新事务,无论当前存不存在事务,都创建新事务。
PROPAGATION_SUPPORTS(根据调用方事务确定):支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
PROPAGATION_NOT_SUPPORTED(挂起已有事务):以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_MANDATORY(没有事务则抛出异常):支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
PROPAGATION_NEVER(有事务就抛出异常):以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。
事务隔离行为
(依靠数据库实现)
(依靠数据库实现)
SOLATION_DEFAULT
用底层数据库的设置隔离级别
ISOLATION_READ_UNCOMMITTED
未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读)
ISOLATION_READ_COMMITTED
提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL server 的默认级别;
ISOLATION_REPEATABLE_READ
可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造
成幻读),MySQL 的默认级别;
成幻读),MySQL 的默认级别;
ISOLATION_SERIALIZABLE
序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读
脏读
表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。
不可重复读
是指在一个事务内,多次读同一数据。而数据不同
幻读
指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。
本质
本身无法提供事务,使用的数据库事务
五种标准的事件类型
上下文更新事件
在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。
上下文开始事件
当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件
上下文停止事件
当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
上下文关闭事件
当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
请求处理事件
在Web应用中,当一个http请求(request)结束触发该事件。
如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。
如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。
基本概念
两个核心
控制反转
解耦
切面编程
以动态非侵入式方式增加服务
缺点
依赖反射,影响性能
风格特点
面向对象编程到面向接口编程
模块
核心容器(Core Container)
Bean
提供BeanFactory,spring将管理对象称为bean
Core
提供框架基本组件,包括控制反转与依赖注入
Context
构建于core之上的context封装,提供框架式的对象访问方法
SpEL
切面编程(Aop,Aspects)
Aop
动态代理切面编程
Aspects
静态代理切面编程
设备支持(Instrumentation)
数据库访问与集成(Data Access/Integration)
JDBC
提供JDBC抽象层
ORM
OXM
JMS
Transaction
Web
WebSocket
Servlet
Web
Portlet
消息(Messaging)
测试(Test)
为测试提供支持,提供了Junit,Testng
AOP
动态代理/静态代理
(spring采用的动态代理)
(spring采用的动态代理)
动态代理(Spring AOP)
动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包
含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
静态代理(AspectJ AOP)
静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到
Java字节码中,运行的时候就是增强之后的AOP对象。
Java字节码中,运行的时候就是增强之后的AOP对象。
方式
JDK动态代理
JDK动态代理是面向接口,在创建代理实现类时比CGLib要快,创建代理速度快。
CGLIB动态代理
CGLib所创立的动态代理商对象在实际运行时候的性能要比JDK动态代理商高
CGLib在创立对象的时候所花费的时间却比JDK动态代理商要多很多
名词
切面Aspect
通知+切点
连接点Join Point
切点Point Cut
通知Advice
切面的工作被称为通知
通知类型
前置通知
后置通知
返回通知
异常通知
环绕通知
引入Introduction
向现有类添加新方法或属性
目标对象Target Object
织入Weawing
切面应用到目标对象并创建新的代理对象的过程
应用的生命周期
编译器
切面在目标类编译时被织入。AspectJ的织入编译器是以这种方式织入切面的
类加载时期
切面在目标类加载到JVM时被织入。
需要特殊的类加载器,它可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5的加载时织入就支持以这种方式织入切面。
需要特殊的类加载器,它可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5的加载时织入就支持以这种方式织入切面。
运行期
切面在应用运行的某个时刻被织入。
一般情况下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。SpringAOP就是以这种方式织入切面。
一般情况下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。SpringAOP就是以这种方式织入切面。
IOC
作用
管理对象的创建与维护
解耦
托管类的生成过程
实现机制
工厂模式+动态代理
支持的功能
依赖注入
组件之间的依赖关系由容器在应用系统运行期来决定
原则
应用组件不应该负责查找资源或者其他依赖的协作对象。
配置对象的工作应该由IoC容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。
容器全权负责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的setter)或者是构造器传递给需要的对象。
配置对象的工作应该由IoC容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。
容器全权负责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的setter)或者是构造器传递给需要的对象。
优势
查找定位操作与应用代码完全无关
不依赖于容器的API,可以很容易地在任何容器以外使用应用对象
不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器
实现方式
接口注入
灵活性、易用性差,spring4已废除
典型应用场景:JNDI
Setter方法注入
有部分注入
会覆盖Setter方法
任意修改不会创建新实例
适用于设置少属性
构造器注入
不会覆盖Setter方法
任意修改会创建新实例
适用于设置很多属性
工厂方法注入
静态工厂方法注入
属性注入(注解直接写在属性上)
利用反射,直接注入属性
单例循环依赖的问题及解决方式
使用三级缓存
三级缓存(singletonFactories ): 单例对象工厂的cache
二级缓存(earlySingletonObjects ):提前暴光的单例对象的Cache
一级缓存(singletonObjects):单例对象的cache
在创建bean的时候,
首先从cache中获取这个单例的bean,这个缓存就是singletonObjects。
如果获取不到,并且对象正在创建中,就再从二级缓存earlySingletonObjects中获取。
如果还是获取不到且允许singletonFactories通过getObject()获取,就从三级缓存singletonFactory.getObject()(三级缓存)获取,如果获取到了则:从singletonFactories中移除,并放入earlySingletonObjects中。
首先从cache中获取这个单例的bean,这个缓存就是singletonObjects。
如果获取不到,并且对象正在创建中,就再从二级缓存earlySingletonObjects中获取。
如果还是获取不到且允许singletonFactories通过getObject()获取,就从三级缓存singletonFactory.getObject()(三级缓存)获取,如果获取到了则:从singletonFactories中移除,并放入earlySingletonObjects中。
Spring解决循环依赖的诀窍就在于singletonFactories这个三级cache
依赖检查
自动装配
支持集合
指定初始化方法和销毁
支持回调某些方法(需要实现接口)
BeanFactory,ApplicationContex
BeanFactory
Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。
延迟加载形式来注入Bean的
总结
加载配置文件,解析成 BeanDefinition 放在 Map 里。
调用 getBean 的时候,从 BeanDefinition 所属的 Map 里,拿出 Class 对象进行实例化,同时,如果有依赖关系,将递归调用 getBean 方法 —— 完成依赖注入。
ApplicationContex
扩展BeadFactory,更完整的框架功
继承MessageSource,因此支持国际化。
统一的资源文件访问方式。
提供在监听器中注册bean的事件。
同时加载多个配置文件。
载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
一次性创建了所有的Bean。
总结
他不仅仅是 IoC。他支持不同信息源头,支持 BeanFactory 工具类,支持层级容器,支持访问文件资源,支持事件发布通知,支持接口回调等等。
0 条评论
下一页