Spring IOC的理解,Bean的生命周期

10 篇文章 8 订阅

spring IOC有两个核心思想就是ioc控制反转和DI依赖注入

ioc控制反转的基本思想是,将原先的对象控制从使用者控制,转交给了spring来控制管理

DI注入就是将对应的熟悉值注入到具体的方法之中

spring提供@Autowired和@Resource等注解注入

对象会存储在map中,在spring使用map结构的singletonObjects存放完整的bean对象

整个bean的生命周期从创建到销毁的过程都由sprin来管理

bean的生命周期

bean的生命周期主要分为初始化使用和销毁

1.在正式进入容器的刷新前会有一些前置操作,确定使用的容器,给开发者提供初始化ApplicationContext的机会

2.初始化BeanFactory,加载bean定义

设置一些相关的参数,将beanName,beanDefintion放入bean工厂,用于后续创建bean对象

3.触发BFPP(BeanFactoryPostProcessor)后处理bean的定义。BFPP接口是spring初始化BeanFactory对外暴露的扩展点,Spring IOC允许BFPP在容器实例化任何bean之前读取bean的定义,并可以在此对bean进行进一步处理。BeanDefinitionRegistryPostProcessor继承自BFPP,具有更高的优先级。

我们也可以implements BeanFactoryPostProcessor 在使用@Component注册到spirng,实现自己的postProcessBeanFactory()逻辑

4.查找该bean所需要的依赖,并将其创建(该Bean已经实例化,但未初始化)/注入到该bean对象中

(在这里可以使用@PostConstruct,注入完成之后)

在注入之后,会完善BFPP的执行部分

setBeanName实现,如果这个bena实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值

BeanFactoryAware实现,如果已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory,setBeanFactory(BeanFactory)传递的是spring工厂自身(可以用这个方式获取其他Bean,只需要在Spring配置文件中配置一个普通的Bean就可以)

ApplicationContextAware实现,如果这个bean实现了ApplicationContextAware接口,会调用setApplicationContextAware(ApplicationContext)方法,传入Spring上下文,这个方式同样可以实现BeanFactoryaware的功能。因为ApplicationContext是BeanFactory的子接口,有更多功能

postProcessBeforeInitialization(Object obj,String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用的方法,也可以被应用于内存或缓存技术

init-method, 如果Bean 在Spring 配置文件中配置了init-method 属性会自动调用其配置的初始化方法。

5.触发BPP(BeanPostProcessor):注册所有的BeanPostProcessor,将所有市县BPP的接口的雷加载到BeanFactory中,BPP接口是Spring初始化bena时对外暴露的扩展点,方便后续对bean对象完成具体的扩展功能。将会调用postProcessAfterInitialization(Object obj, String s)方法。

6,生成完整的bean对象,通过getBean的方法可以直接获取使用

注:以上工作完成以后就可以应用这个Bean 了,那这个Bean 是一个Singleton 的,所以一般情况下我们调用同一个id 的Bean 会是在内容地址相同的实例,当然在Spring 配置文件中也可以配置非Singleton。Destroy 过期自动清理阶段

使用

  • spring使用反射创造代理对象操作bean
  • spirng会通过Proxy,jdk接口,CGLib代理创建代理对象,在对象的基础上使用代理操作对象
  • spring boot优先使用CGLib创建代理

销毁

在这里可以使用@PreDesTroy注解(销毁之前)

当Bean 不再需要时,会经过清理阶段,如果Bean 实现了DisposableBean 这个接口,会调用那个其实现的destroy()方法;destroy-method 自配资清理。在BeanFactory关闭的时候,Bean的生命周期会调用以下方法.

  • DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(),可以调用自定义回调,像是DisPosaBleBean的销毁和自定义销毁方法,这个回调仅适用于工厂中的单例Bean
  • 实现了自定义的destory()方法

Bean的生命周期方法:@PostConstruct和@PreDesTroy

要求:需要是自己编写的类,不是自己的类无法使用注解,只能使用Bean的属性

可以在对象注入之后和销毁之前编写一些代码逻辑,检查内容等

被组件扫描发现后,会自动添加启动和关闭的行为,不可以有返回值与参数

@PostConstruct 所有依赖注入后启动

@PreDesTroy结束时,bean实例销毁之前启动

注意仅当程序是正常关闭时,在会调用preDestroy方法,如果是意外错误,强制中止,不会调用

总结

bean是一个由Spring IOC容器初始化,组装和管理的对象

BeanDefinition是bean的定义,存储bena等等所有方法,属性定义。

ApplicationContext是BeanFactory的子接口,是相对较高级的IOC容器实现。包含BeanFactory的所有功能,还提供了其他的高级特性,比如时间发布,国际化信息支持,统一资源加载策略。

BeanFactory是最基础的IOC容器,提供完整的IOC服务支持

FactoryBean是一种特殊的bena,他是工厂bean,可以自己创建Bean实例

如果一个类实现了FactoryBean接口,该类可以自己定义创建实例对象的方法,只需实现getObjecte()方法即可

IOC的三级缓存是什么

 三级缓存(单例工厂)singleFactories :存放ObjectFactory传入时的匿名内部类,返回Bean实例化的Lambda表达式,产生Bean对象

二级缓存二级缓存(早期的单例对象)earlySingletonObjects:存放未被完全创建好的bean对象,判断该对象是否需要被代理

  • 不需要,产生bean实例
  • 需要,产生代理实例

一级缓存(单利池)singletonObjects:存放完整的bean对象

/**单例对象的缓存:从bean名称到bean实例。   */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/**早期单例对象的缓存:从bean名称到bean实例。 */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/**单例工厂的缓存:对象工厂的bean名称。   */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

bean的初始化过程中循环依赖和解决

A类中有一个属性B类,那么spring在创建A对象的时候发现了需要一个B对象,这个时候spring就会暂时停止对A的创建,会先去创建B对象,等B对象创建完之后,将B对象注入到A对象中,再接着创建A对象剩下的工作。

创建bean的过程我们可以分为两部分:

  1. 通过反射,BFPP定义出一个对象(但是不会初始化),将A对象标为正在创建中,并且放到缓存中。
  2. 查看它的依赖,再通过BPP往对象中的属性赋值,初始化

第二步中,会先查询是否有依赖需要注入,如果有,spring会先去寻找这个bean对象,有的话直接ID注入,没有则创建中的B对象,将其注入之后再继续创建A对象

在b对象创建时同样会经过这两步,同样在标记b对象正在创建中,存入缓存中后,查找其依赖的A对象,此时发现A对象正在创建中,将这个创建中的A对象为B对象注入,完成B对象的创建

创建好B对象之后,回到A对象,完善A对象的创建

涉及到的模式概念:

享元模式:bean池是一个享元模式

工厂模式:XXXFactory,产生对象的工厂

单例模式:Spring 中 bean 的默认作用域就是 singleton(单例)的。

策略模式:Spring需要针对不同的资源采取不同的访问策略

装饰模式:通过使用修饰模式,可以在运行时扩充一个类的功能。

....

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值