Spring Framework系统架构
Spring Framework是Spring生态圈中最基础的项目,是其他项目的根基
Core Container:核心容器
AOP:面向切面编程
Aspects:AOP思想实现
Data Access:数据访问
Data Integration:数据集成
Web:Web开发
Test:单元测试与集成测试
代码书写现状
耦合度偏高
解决方案
使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象
IoC控制反转
对象的创建控制权由程序转移到外部,这种思想称为控制反转
就是一件事,解耦
IoC(Inversion of Control)控制反转
使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
Spring技术对IoC思想进行了实现
Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的“外部”
IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
DI 依赖注入
在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
目标:充分解耦
使用IoC容器管理bean(IoC)
在IoC容器内将有依赖关系的bean进行关系绑定(DI)
最终效果
使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系
IoC入门案例思路分析
1.管理什么?(Service与Dao)
2.如何将被管理的对象告知IoC容器?(配置)
3.被管理的对象交给IoC容器,如何获取到IoC容器?(接口)
4.IoC容器得到后,如何从容器中获取bean?(接口方法)
5.使用Spring导入哪些坐标?(pom.xml)
一个类中,所有的方法,都是抽象方法
制定规则
接口
当一个类中的所有方法都是抽象方法的时候,我们就可以将其定义为接口
接口也是一种引用数据类型,它比抽象类还要抽象
接口存在的两个重要意义
1.规则的定义
2.程序的扩展性
接口用关键字interface来定义
接口不能实例化
接口和类之间是实现关系
接口的子类(实现类)
要么重写接口中的所有抽象方法
要么是抽象类
创建一个接口文件,用一个类h去实现接口并且重写接口,然后再到测试类new一个h的对象,就可以通过h调用h里面重写的方法了。
一个类可以实现多个接口,只要重写接口里面的方法就可以了。
IoC容器就是IoC思想中的“外部”。
IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
业务层实现,依赖dao对象运行
IoC容器
service依赖dao
DI依赖注入
在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
目标:充分解耦
使用IoC容器管理bean(IoC)
在IoC容器内将有依赖关系的bean进行关系绑定(DI) 将有依赖关系的bean进行关系绑定(DI)
最终效果
使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系
IoC入门案例思路分析
1.管理什么?
-> Service与Dao
2.如何将被管理的对象告知IoC容器?
->配置
3.被管理的对象交给IoC容器,如何获取到IoC容器?
-> 接口
4.IoC容器得到后,如何从容器中获取bean?
-> 接口方法
5.使用Spring 导入哪些坐标?
pom.xml
用bean标签配置bean
id属性标识给bean起名字
class属性标识给bean定义类型
注意事项:bean定义时id属性在同一个上下文中不能重复
获取IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext( configlocation: "applicationContext.xml"):
获取bean
ctx.getBean( s:"bookDao"); 这个bookDao就是pom.xml文件里定义的id属性标识
DI入门案例思想分析
1.基于IoC管理bean
2.Service中使用new形式创建的Dao对象是否保留?
->否
3.Service中需要的Dao对象如何进入到Service中?
->提供方法
4.Service与Dao间的关系如何描述?
set方法就是传一个对象给 bookDao
property标签表示配置当前bean的属性
name属性表示配置哪一个具体的属性
ref属性表示参照哪一个bean
<property name="bookDao"” ref="bookDao"/>
name="bookDao"里的bookDao指的是
注意事项:
获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常NoSuchBeanDefinitionException
name属性,所属bean标签,功能:定义bean的别名,可定义多个,使用逗号(,)分号(;)空格( )分隔
只要配置一下这个 scope属性,可以控制bean造出来的对象不是同一个
scope属性所属bean标签,功能:定义bean的作用范围,可选范围如下:
singleton:单例(默认),prototype:非单例
为什么bean默认为单例?
因为如果不是单例的话,那么造一个对象就多一个,长此以往下去,对象就会无限多,容器的压力就会非常大。
适合交给容器进行管理的bean
表现层对象
业务层对象
数据层对象
工具对象
不适合交给容器进行管理的bean封装实体的域对象
bean实例化
bean本质上就是对象,创建bean使用构造方法完成
实例化bean的三种方式——构造方法(常用)
无参构造方法如果不存在,将抛出异常BeanCreationException
初始化容器
1.创建对象
2.执行构造方法
3.执行属性注入(set操作)
4.执行bean初始化方法
使用bean
执行业务操作
关闭/销毁容器
执行bean销毁方法
容器关闭前触发bean的销毁
关闭容器方式
手工闭关容器
注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机
依赖注入方式
思考:向一个类中传递数据的方式有几种?
普通方法(set方法)
构造方法
思考:依赖注入描述了在容器中建立bean与bean之间依赖关系的过程,如果bean运行需要的是数字或字符串呢?
引用类型
简单类型(基本数据类型与String)
依赖注入方式
setter注入
简单类型
引用类型
构造器注入
简单类型
引用类型
setter注入——简单类型
1.在bean中定义引用类型属性并提供可访问的set方法
2.配置中使用property标签value属性注入简单类型数据
依赖注入方式选择
1.强制依赖使用构造器,使用setter注入有概率不进行注入导致null对象出现
2.可选依赖使用setter注入进行,灵活性强
3.Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
4.如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter方法就必须使用构造器注入
5.实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
6.自己开发的模块推荐使用setter注入
依赖自动装配
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
自动装配·方式
按类型(常用)
按名称
按构造方法
不启用自动装配
只要加上autowire属性,并且设置byType,它就按类型分配了
配置中使用bean标签autowire属性设置自动装配的类型
依赖自动装配特征
自动装配用于引用类型依赖注入,不能对简单类型进行操作
使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
使用按名称装配时(byNmae)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
给集合和数组注入:你要写值得就直接写就行
接口中的成员变量,只能是常量。比如int num = 10, 系统会默认在前面加上public static final。所以,我们不能在实现类里面去给这个变量赋值。
接口中的方法,只能是抽象方法,系统会在前面自动加上 public abstract修饰符
JDK8版本后,允许在接口中定义非抽象方法,但是需要使用关键字default修饰,这些方法就是默认方法
作用:解决接口升级的问题
即使在接口中新增了十多个方法,实现类的代码也无需更改
接口中默认方法的注意事项:
默认方法不是抽象方法,所以不强制被重写。但是可以被重写,重写的时候去掉default关键字
public可以省略,default不能省略
如果实现了多个接口,多个接口中存在相同的方法声明,子类就必须对该方法进行重写(以实现类重写的方法为准)
接口中允许定义static静态方法
如何调用接口中的静态方法?
->直接用接口的类名调用方法
因为静态方法都是通过类名调用的,所以即使两个接口中出现了名字一样的方法,也不会发生逻辑冲突的问题。
静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
public可以省略,static不能省略
只为接口服务,不需要外部访问的,可以进行私有化,用private修饰即可。
接口→实现类重写接口→测试类调用实现类
静态方法只能通过接口名调用
接口的使用思路
如果发现一个类中所有的方法都是抽象方法,那么就可以将该类,改进为一个接口
涉及到了接口大面积更新方法,而不想去修改每一个实现类,就可以将更新的方法,定义为带有方法体的默认方法
希望默认方法调用的更加简洁,可以考虑设计为static静态方法。(需要去掉default关键字)
默认方法中出现了重复的代码,可以考虑抽取出一个私有方法
一个类继承了一个父类又实现了一个接口,父类和接口中出现了相同的方法声明,但是代码逻辑不一样,优先使用父类的逻辑。
当一个类中的所有方法都是抽象方法的时候,我们就可以将其定义为接口
接口也是一种引用数据类型,它比抽象类还要抽象
接口存在的两个重要意义
规则的定义
程序的扩展性
继承概述
根据多个类中共性的内容,向上抽取而来
继承:让类与类之间产生关系(子父类关系),子类可以直接使用父类中非私有的成员
继承的好处:提高了代码的复用性
Spring Framework是Spring生态圈中最基础的项目,是其他项目的根基
Core Container:核心容器
IoC 控制反转
使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
Spring技术对IoC思想进行了实现
Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的“外部”。
IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
DI 依赖注入
在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
目标:充分解耦
使用IoC容器管理bean(IoC)
在IoC容器内将有依赖关系
1.管理什么?(Service与Dao)
2.如何将管理的对象告知IoC容器(配置)
3.被管理的对象交给IoC容器,如何获取到IoC容器?(接口)
4.IoC容器得到后,如何从容器中获取bean?(接口方法)
5.使用Spring导入哪些坐标?(pom.xml)
DI入门案例思路分析
1.基于IoC管理bean
2.Service中使用new形式创建的Dao对象是否保留(否)
3.Service中需要的Dao对象如何进入到Service中?(提供方法)
4.Service与Dao间的关系如何描述?(配置)
scope属性可以设置对象为单例还是非单例,单例就是每次给你的对象,你去读取对象的地址,你会发现都是一样的地址,每次给你的对象都是一样的,反之,非单例每次给你的对象都是新建的。
为什么bean默认为单例?
如果不是单例的话,它每次都需要新建一个对象,那么就需要耗费很大的资源,这也是一种负担。
适合交给容器进行管理的bean
表现层对象
业务层对象
数据层对象
工具对象
不适合交给容器进行管理的bean
封装实体的域对象
bean本质上就是对象,创建bean使用构造方法完成
它的bean是不能带参的