Spring系列——深入学习IOC

Ioc基本概念

全称: Inversion of Control (IOC) 名为:控制反转 轻量级容器

控制权转移,将我们创建的对象的方式反转了,以前的对象的创建时由开发人员自己维护,包括依赖对象也是自己注入,使用了spring之后,对象的创建以及依赖关系可以由spring完成创建以及注入,反转控制就是反转了对象的创建方式,从我们自己创建反转给了程序创建(Ioc Service Provider)

别名 :DI 依赖注入 Dependency Injection 可以看作IOC注入的一种方式。

底层原理: XML 解析 工厂模式 反射

Ioc注入方式

构造方法注入

​ 通过其构造方法中声明依赖对象的参数列表,通过Ioc检查注入对象的构造方法,取得依赖对象列表,从而注入对象。

setter方法注入

​ 与构造方法相似,一个类中通常都有getXXX和setXXX方法访问类属性。Ioc通过调用setter方法取得依赖对象并设置到注入对象中。

接口注入

​ 接口注入相对复杂,通过接口注入依赖对象,则注入对象必须实现某接口,该接口必须提供一个可以注入依赖对象的方法。该方法的参数就是所依赖对象的类型。

三种注入方式的比较:

​ 1、接口注入基本不使用。由于可能需要实现不必要的接口,带有侵入性。

​ 2、构造方法注入,对象构造完成后,立即进入准备状态,马上使用。缺点:对于参数过多的构造方法,参数列表较长,使用和维和麻烦,不可设置默认值,不可被继承,对参数数量的变动维护不变。

​ 3、setter方法注入。方法名自定义,可以被继承,允许有默认值。

Ioc优势

降低组件之间的耦合度,实现软件各层之间的解耦.

Ioc Service Provider

职责:业务对象的构建管理和业务对象间的依赖绑定

Ioc Service Provider管理对象方式

1、直接编码方式

![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ek6rTRnO-1646801947200)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210903213606107.png)]](https://img-blog.csdnimg.cn/dbba5daa51544d9ba3f7fcc13f1f68b6.png

通过为响应类指定对应的具体实例,告知Ioc容器,当需要对象实例时,将容器中的实例返回给我们。

2、配置文件方式

​ Spring采用XML文件管理和保存依赖注入关系。

3、元数据方式

​ 以注解的方式,可以在类中那个使用元数据信息来标注各个对象之间的依赖关系。

Ioc容器之Beanfactory

两种容器类型:

1、Beanfactory :基础类型Ioc容器,对资源有限,并且要求不严格的场景,选用该容器 Interface

​ (1) spring的原始接口,针对原始接口的实现类功能较为单一
​ (2)BeanFactory接口实现类的容器,特点是每次在获得对象时才会创建对象

2、ApplicationContext 继承于Beanfactory,在Beanfactory的基础上构建,高级容器实现,支持所有Beanfactory。较Beanfactory 需要更多资源,启动时完成所有初始化,启动时间较Beanfactory长。

​ (1)每次容器启动时就会创建容器中配置的所有对象
​ (2)提供了更多功能
​ (3)从类路径下加载配置文件: ClassPathXmlApplicationContext
​ 从硬盘的绝对路径下加载配置文件:FileSystemXmlApplication

关系:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bEkqHsPg-1646801947201)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210903214746417.png)]
Beanfactory接口中getBean方法 获取对象的方法,containBean查询某个对象是否存在容器中的方法。

getBean(String name,Class requiredType)

containBean(String name)

Beanfactory的对象注册于依赖绑定方式

1、直接编码方式

DefaultListableBeanFactory是BeanFactory一个通用实现类,DefaultListableBeanFactory间接实现Beanfactory接口。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r6DeukiE-1646801947201)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210903221542541.png)]
2、外部配置文件方式

​ 配置流程:

​ 根据不同的文件格式给出相应的BeanDefinitionReader实现类,由BeanDefinitionReader的相应实现类负责将将相应的配置文件内容读取并映射到BeanDefinition,然后将映射的BeanDefinition注册一个BeanDefinitionRegistry,之后BeanDefinitionRegistry完成Bean的注册和加载。

在这里插入图片描述
​ Ioc容器支持properties和XML两种文件格式

①properties 配置 是按照Spring自己文件配置规则进行加载,可以自定义.

PropertiesBeanDefinitionReader类实现Properties格式配置文件加载

​ ②XML配置

​ XMLBeanDefinitionReader类负责读取并解析XML文件配置

​ ③注解方式 需要在XML文档内配置 classpath-class

​ <context:component-scan base-package = ‘’ classpath-class’’/>

​ @Autowired 告诉Spring容器注入对象

​ @component 对相关类进行标记

Beanfactory的XML

1 、beans 和bean

​ 所有的均在之下

​ 默认设置: lazy-init :延迟初始化 true false 默认no

​ autowire 绑定方式 byType byName no 默认no

​ dependency-check 依赖检查none objects simple all 默认none

​ init-method 初始化方法 在 和设置

​ destory-method 销毁方法 在 和设置

​ 配置文件描述信息,非必须

​ 从A.XML引入B.XML是使用 形式 多个XML文件时,可以使用

​ 对bean取别名

属性:

​ ①id属性 与name属性一模一样,名称不可重复,不能使用特殊字符

​ ②name属性 给被管理的对象起个名字,获得对象时getBean(“name值”),可以使用特殊字符 可以用alias取别名

​ ③class 属性 被管理对象的完整类名(类路径)

2 、构造方法注入

​ ① <name = “构造函数参数名”> 输入构造函数参数名

​ ②<index = “构造函数参数下标(从0开始)”> 功能于name相似 可替换name

​ ③<value = “参数值”>

​ ④<type = “参数类型”>构造函数的参数类型

​ 或者

⑤<ref  = "依赖对象名称">  

3、setter方法注入

​ ① <name = “构造函数参数名”> 输入构造函数参数名

​ ②<value = “参数值”>

​ ③<index = “构造函数参数下标(从0开始)”> 功能于name相似 可替换name

或者

​ ④<ref = “依赖对象名称”> 内嵌其他元素来指定具体的依赖对象引用

4、properties和constructor-arg可用的配置项

(1) 值 最底层元素 不可嵌套任何元素

(2) 用于引用容器中的其他对象,其包含 local parent 和 bean属性来表名引用对象的beanName是什么

​ ①local 指定当前配置对象在同一配置文件的对象定义的名称

​ ②parent 指定位于当前容器的父容器中定义的对象的引用(Beanfactory可以分层次,通过实现HierarchicalBeanFactory接口,实现容器A,引用容器B)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GWHmJrzf-1646801947202)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904143037386.png)]
​ ③bean 以上均可,一般用bean

(3) 为当前依赖对象注入所依赖对象 不常用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2ay0B9LA-1646801947202)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904143320309.png)]
作用同于:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-12q3xc43-1646801947202)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904143402285.png)]
(4) 内部 bean内部嵌套

(5)

… …

(6)

… …

(7)

… …

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AM2ewmq3-1646801947203)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904144045201.png)]

(8) key键值于value值相映射

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8qmxNFwH-1646801947203)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904144442953.png)]
(9)

当对象为String类型时, 不等价于""

==

5、显式依赖

若一个类需要初始化代码

<depends-on =“依赖对象”> 显示指定bean之间的关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WXjMr9MZ-1646801947203)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904150427105.png)]

6、autowire

<autowire = “”>

Spring提供了五种自动绑定关系: no byType byName constructor autodetect 默认no

no 不采用任何自动绑定

byType 按实例变量类型自动绑定

byName 按实例变量名称自动绑定 与beanName的值进行匹配

constructor 按构造方法参数类型进行自动绑定

autodetect byTyoe和constructor,若默认无参数的构造方法,容器会优先考虑byType的自动绑定模式,否则使用constructor模式绑定

7、dependency-check

<denpendecy-check = “”>

每个bean都有一个dependency-check属性,其所有来的对象进行最终检查

none 默认值,不进行检查

simple 顾名思义简单检查,只对相关collection进行检查,对象引用类型的依赖除外.

object 只对对象引用类型依赖进行检查

all = simple + object

该一般属性不使用

8、lazy-init 延迟初始化

<lazy-init = “ture or false”>

延迟某些bean或者某个beanApplicationContext默认初始化时机.

为保证该bean定义的其他bean定义也同样设置为延迟初始化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ooiWf7fO-1646801947203)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904154050459.png)]
一般在中统一设置

9、bean中的继承

<parent = “父类名称”>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KkQ3Xi52-1646801947204)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904154857846.png)]

10、bean中的scope

​ <scope="">

singleton Spring在Ioc中只会存在一个实例,该属性下,通过getBean得到的对象,指向同一个对象

prototype 每次请求都会返回一个新的实例

request 针对Web 每次HTTP请求都会建立一个全新的对象,为prototype特例

session 对每个session都会常见新的UserPreferences对象实例

工厂方法和工厂bean

1、静态工厂方法

​ 获得实例的方法为静态方法

​ <factory-method = “静态工厂方法”>

在这里插入图片描述

2、非静态方法

​ 获得实例的方法为非静态方法

​ <factory-method = “静态工厂方法”>

3、FactoryBean

通过工厂Beanfactory,配置文件定义的Bean类型可以和返回类型不一样

FactoryBean创建步骤:

​ ①创建类,作为工厂Bean.实现FactoryBean

​ ②重写接口方法,在getObject方法中返回需要的Bean类型

FactoryBean为Bean提供的一个实例化接口,其定义了三个方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CVmDjM34-1646801947204)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904163808383.png)]
getObject()方法会返回该FactoryBean“生产”的对象实例,我们需要实现该方法以给出自己 的对象实例化逻辑;

getObjectType()方法仅返回getObject()方法所返回的对象的类型,如果预先 无法确定,则返回null;

isSingleton()方法返回结果用于表明,工厂方法(getObject())所“生 产”的对象是否要以singleton形式存在于容器中。如果以singleton形式存在,则返回true,否则返回false;

scope陷阱

当bean中的scope属性定义为prototype后,每次实例化返回一个全新的该对象实例,

存在下面特例:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eEUELqRR-1646801947204)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904165759417.png)]
通过getBean获得实例,每次调用persistNews方法时,都会调用,getNewsBean方法,该方法多次调用的方法,都是指向同一个引用对象,所以要解决getBean调用单一实例.

1、注入方法

通过的name属性指定需要注入的方法名,bean属性指定需要注入的对象,当 getNewsBean方法被调用的时候,容器可以每次返回一个新的FXNewsBean类型的实例。

2、使用BeanFactoryAware接口

实现该接口里面的setBeanFactory方法
在这里插入图片描述

3、方法替换

不建议这么做

容器背后的秘密

Ioc容器分为容器启动阶段和Bean实例化阶段

在这里插入图片描述

1、容器启动阶段

容器通过某些工具类将XML文档解析并编为相应的BeanDefinition,保存Bean必要的信息BeanDefinition,注册BeanDefinitionRegistery.

映射流程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ktgtBySX-1646801947205)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904182734046.png)]
BeanFactoryPostProcessor容器扩展机制,对注册到BeanDefinition的信息做出相应的修改.

①PropertyPlaceholderConfigurer

​ 该类允许在XML配置文档中使用占位符(PlaceHolder) 例如连接数据库的4条基本信息

<?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:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--直接配置连接池-->
<!--<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/userDb"></property>
    <property name="username" value="root"></property>
    <property name="password" value="root"></property>
</bean>-->

<!--引入外部属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>

<!--配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${prop.driverClass}"></property>
    <property name="url" value="${prop.url}"></property>
    <property name="username" value="${prop.userName}"></property>
    <property name="password" value="${prop.password}"></property>
</bean>
    </beans>

PropertyPlaceholderConfigurer不单会从其配置的properties文件中加载配置项,同时还会检 查Java的System类中的Properties,可以通过setSystemPropertiesMode()或者setSystemPropertiesModeName()来控制是否加载或者覆盖System相应Properties的行为。

​ ②PropertyOverrideConfigurer

可以通过PropertyOverrideConfigurer对容器中配置的任何你想处理的bean定义的property信息进行覆盖替换。

​ ③ CustomEditorConfigurer

2、实例化过程

当getBean方法请求某个对象时,会根据注册的BeanDefinition所提供的信息实例化被请求对象.

Bean的生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OVjitkEX-1646801947205)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904184832250.png)]

简化过程:

①通过构造器创建Bean实例(无参数构造)

②为bean的属性设置值和对其他bean引用(调用set方法)

③把bean实例传递给bean后置处理方法postProcessBeforeInitialization

④调用bean初始化方法(需要配置init-method)

⑤把bean实例传递给bean后置处理方法postProcessAfterInitialization

⑥使用bean

⑦容器关闭.调用bean销毁方法(需要配置destory-method)

其中③和⑤需要创建类,实现BeanPostProcessor,重写postProcessBeforeInitialization和postProcessAfterInitialization方法,在XML文档内需要配置后置处理器

各种Aware接口

BeanNameAware 该对象实例的bean定义对应的beanName设置到当前对象实例

BeanClassLoaderAware 容器检测到当前对 象实例实现了该接口,会将对应加载当前bean的Classloader注入当前对象实例。

BeanFactoryAware 将自身设置到当前对象实例

ResourceLoaderAware

ApplicationEventPublisherAware

MessageSourceAware

ApplicationContextAware

Ioc容器ApplicationContext

Spring为基本的BeanFactory类型容器提供了XmlBeanFactory实现。

ApplicationContext提供了如下实现:

FileSystemXmlApplicationContext 从文件系统加载bean定义以及相关资源的ApplicationContext实现

ClassPathXmlApplicationContext 从Classpath加载bean定义以及相关资源的ApplicationContext实现

Spring资源加载策略

Resource接口作为所有资源的抽象和访问接口

提供如下类以供实现:

①ByteArrayResource 将字节(byte)数组提供的数据作为一种资源进行封装,如果通过 InputStream形式访问该类型的资源,该实现会根据字节数组的数据,构造相应的ByteArrayInputStream并返回。

②ClassPathResource 该实现从Java应用程序的ClassPath中加载具体资源并进行封装,可以使 用指定的类加载器(ClassLoader)或者给定的类进行资源加载。

③FileSystemResource 我们可以以文件或者URL的形 式对该类型资源进行访问,只要能跟File打的交道,基本上跟FileSystemResource也可以。

④UrlResource 通过java.net.URL进行的具体资源查找定位的实现类,内部委派URL进行具 体的资源操作。

⑤InputStreamResource 将给定的InputStream视为一种资源的Resource实现类,较为少用。 可能的情况下,以ByteArrayResource以及其他形式资源实现代之。

ResourceLoader 接口

用于定位和查找资源

提供如下类:

①DefaultResourceLoader

②FileSystemResourceLoader

③ ResourcePatternResolver ——批量查找的ResourceLoade

ApplicationContext与Resource

在这里插入图片描述
通过ApplicationContext来加载任何Spring支持的Resource类型,ApplicationContext容器本身就是一个ResourceLoader

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gwPBi67F-1646801947206)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210904192804338.png)]

国际化信息支持

1、Locale类

提供了三个构造方法

​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ur6c8udk-1646801947206)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210906101416643.png)]
Locale china = new Locale(“zh”,“CN”);

相当于 Locale.CHINA

Locale.CHINA代表中国,表示zh_CN

Locale.US代表美国地区,代码表示为en_US

2、ResourceBundle类

​ 用来保存特定于某个Locale的信息(可以是String类型信息,也可以是任何类型的对象)

3、MessageSource 接口

​ 该接口定义了三种方法,实现该接口需要重写下列方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pkddZR4l-1646801947206)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210906102405241.png)]

他有以下实现类:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kI1hDuK8-1646801947206)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210906102518582.png)]

基于注解方式的Ioc操作Bean管理

格式: @注解名称(属性名称=属性值,属性名称=属性值)

Spring 针对 Bean 管理中创建对象提供注解

(1)@Component (2)@Service (3)@Controller (4)@Repository

  • 上面四个注解功能是一样的,都可以用来创建 bean 实例,一般在不同地方规定使用某一个关键字。提高可读性

基于注解方式实现对象创建步骤

①引入spring-aop-release依赖

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-buGXjmDX-1646801947207)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210906104003154.png)]
②在XML文件中开启扫描

​ <context:component-scan base-package=“目录名”></context:component-scan>>

③ 创建类 ,在类上添加创建对象注解

@Component(value = “对象名”) //不写value 默认对象名为类名开头字母为小写

class 类名{

}

等价于

④扫描细节配置 可以设置哪些不扫描、哪些扫描

<use-default-filters = “false ot true”> 是否是哟默认的filters ,若为false,自己设置扫描内容。

<use-default-filters = “false” type = “Component or Service …”>对某一注解方式进行扫描

⑤注解方式的属性注入

​ (1) @autowire 根据属性类型进行自动装配

​				[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LRpHZacN-1646801947207)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210906105146465.png)]
​ (2) @Qualifier 根据名称进行注入 需要通@autowire一同使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e9NTeKQS-1646801947207)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210906105308288.png)]
​ (3)@Resource 既可根据名称,也可根据名称注入
在这里插入图片描述
​ (4)@Value 可以注入普通类型属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lIdWbPeN-1646801947207)(C:\Users\崔常菲\AppData\Roaming\Typora\typora-user-images\image-20210906105447658.png)]

​ (5)完全注解开发

​ @Configuration(bakPages={“路径”,…}//作为配置类,替代 xml 配置文件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值