SpringIOC以及bean
一、什么是IoC?
控制反转,是面向对象编程中的一种设计原则,降低代码之间的耦合度。其中最重要的方式为依赖注入(DI),通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所以来的对象的引用传递给它。
二、IOC的原理
IOC底层原理就是java反射。给定一个字符串就能传一个实例,利用set方法对实例的依赖进行注入;
关于java反射在前面的文章已经学习过了,如何创建一个对象并执行这个对象的方法。
在springIOC中,我们只需要在配置文件中给定一个类名字字符串,对象就会被创建出来,系统启动完毕之后,我们只需要直接声明对象就可以使用了,不用自己去new。IOC通过反射调用方法的setText方法,完成依赖注入(给对象属性赋值)。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。
BeanFactory
-
定义:
BeanFactory定义了IOC容器最基本形式,并提供了IOC容器应遵守的最基本的接口,是SpringIOC所遵守的最底层和最基本的编程规范。spring中,BeanFactory只是一个接口,并不是IOC容器的具体实现,像DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,都是对BeanFactory接口附加了某种功能的实现。
-
接口定义的方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OPzhxY94-1653379950961)(C:\Users\Leejie\Desktop\leejie\笔记\image\1653294080502.png)]
-
BeanFactory作用
在spring中,所有的对象bean的生产都是通过beanFactory来实例化的,beanFactory可以在实例化bean的过程中对bean进行一些额外的处理。beanFactory会在bean的生命周期的各个阶段中对bean进行各种管理,并且spring将这些阶段通过各种接口暴露给我们,让我们可以对bean进行各种处理,我们只要让bean实现对应的接口,那么spring就会在bean的生命周期调用我们实现的接口来处理该bean。
关于BeanFactory生成bean的过程可以看一下这篇文章:https://blog.csdn.net/qq_36688143/article/details/84968036
ApplicationContext
应用上下文,继承了BeanFactory接口,它是Spring中一个更高级的容器,提供了更多的功能。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0GOY5Ydr-1653379950962)(C:\Users\Leejie\Desktop\leejie\笔记\image\0524ApplicationContext.png)]
ApplicationContext继承了HierachicalBeanFactory和ListableBeanFactory接口,在此基础上,还通过其他接口扩展了BeanFactory的功能。
ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器的启动事件、关闭事件等。
MessageSource:为应用提供i18N国际化消息访问的功能。
ResourcePatternResolver:加载资源,可以通过带前缀的Ant风格的资源文件路径装载Spring的配置文件。
ApplicationContext两个主要实现类:
- ClassPathXmlApplicationContext
- FileSystemXmlApplicationContext
通过这两个实现类可以读取配置bean的xml文件,并获取到bean对象。
BeanFactory和ApplicationContext的区别
装载bean的区别:
BeanFactory在初始化容器时,并没有实例化Bean,直到第一次访问某个Bean时才实例化目标Bean。
ApplicationContext会在初始化应用上下文时就实例化所有单实例的Bean,还可以为Bean配置lazy-init=true来让Bean延迟实例化。
Bean生命周期
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I6S0I7zi-1653379950963)(C:\Users\Leejie\Desktop\leejie\笔记\image\bean生命周期.jpg)]
- 实例化bean对象(通过构造方法或者工厂方法)
- 设置对象属性(setter等)(依赖注入)
- 如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。
- 如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身
- 将Bean实例传递给Bean的前置处理器的postProcessBeforeInitialization(Object bean, String beanname)方法
- 调用Bean的初始化方法
- 将Bean实例传递给Bean的后置处理器的postProcessAfterInitialization(Object bean, String beanname)方法
- 使用Bean
- 容器关闭之前,调用Bean的销毁方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4WoTpUdG-1653379950963)(C:\Users\Leejie\Desktop\leejie\笔记\image\bean.png)]
Bean作用域
Spring中的bean默认是单例的,对于Web应用来说,Web容器对于每个用户请求都创建一个单独的Servlet线程来处理请求,引入Spring框架之后每个Action都是单例的,那么对于spring托管的单例Service bean,Spring的单例是基于BeanFactory的,单例bean在spring容器中只有一个,Java的单例是基于JVM,每个JVM内只有一个实例。
类别 | 说明 |
---|---|
singleton | 在spring IOC容器中仅存在一个bean实例,bean以单例方式存在,默认值 |
prototype | 每次从容器中调用bean时,都返回一个新的实例。 |
request | 每次HTTP请求都会创建一个新的bean,该作用域只适用于WebApplicationContext环境 |
session | 同一个HTTP Session 共享一个bean,不同Session使用不同bean,仅适用于WebApplicationContext环境 |
globalSession | 一般用于Protlet应用环境,该作用域仅适用于WebApplicationContext环境 |
- 当一个bean的作用域为singleton,那么Spring IOC容器只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
- 当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。Prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。
<bean id="life_singleton" class="com.bean.LifeBean" scope="singleton"
init-method="init" destroy-method="destory" lazy-init="true"/>