首页 > 编程知识 正文

spring容器生命周期和bean生命周期,spring ioc容器中对象的生命周期

时间:2023-05-04 05:04:19 阅读:182262 作者:1982

Spring容器的生命周期执行configurableapplicationcontext.refresh (方法是Spring容器生命周期开始的主要入口。 但是,调用beandefinitionregistrypostprocessor和BeanFactoryPostProcessor这两个后处理是最重要的步骤。 configurationclasspostprocessor使用postprocessbeandefinitionregistry (beandefinitionregistryregistry )方法,http://ww.Sina.Sina

BeanDefinition BeanDefinition是用于描述Bean信息的接口,例如具有哪些属性、如何生成方法参数、Bean的范围是什么以及是否忽略读取。 调用applicationContext.getBean(…)获取Bean实例对象时,如果尚未创建Bean,则会根据BeanDefinition的描述信息创建Bean。 BeanDefinition提供了以下重要的实现类:

启动类使用了AnnotatedGenericBeanDefinition包。 通过classpath执行包扫描所扫描的类使用: scannedgenericbeandefinition,可以在classpathscanningcandidatecomponentprovider 418行中查看导入的bean使用AnnotatedGenericBeanDefinition。

例如,在:spring.factories中配置的类是由启动类导入的Bean,而非静态内部配置类是org.spring framework.context.annotation.configing

调用applicationContext.getBean ()检索Bean时,如果尚未创建Bean对象,则为abstract beanfactory.getmergedlocalbeandefinition 将各种类型的Beandefinition转换为RootBeanDefinition,以便将BeanFactoryPostProcessor在中文中识别为bean。开发人员可以通过实现此接口, 用其接口方法postprocessbeanfactory (configurablelistablebeanfactorybeanfactory )在beanfactory中修改现有的实现classpath下指定包中的类文件扫描。

beandefinitionregistrypostprocessor是BeanFactoryPostProcessor的子类,用于存储postprocessbeandefinitionregistry (

但是,子类的postprocessbeandefinitionregistry (…)方法在父类的postProcessBeanFactory(…) )方法之前执行。

2.1preparerefresh )方法来激活容器调用此方法是为了将AbstractApplicationContext的AtomicBoolean active成员变量的值设置为true

2.2设置configurablelistablebeanfactory对象所需的必需组件prepare beanfactory (configurablelistablebeanfactorybeanfactory )此方法

添加SpringEL表达式解析器添加applicationcontextawareprocessor后处理器,用于检测实例化Bean时是否实现了aware方法并实现注入。 添加ApplicationListenerDetector后处理器以检测是否在bean中实现了ApplicationListener,如果实现了,则为AbstractApplicationContext的侦听器内核2.3调用beanfactorypostprocessor实现包扫描,由beanfactorypostorypostioncontext成员变量beanFactoryPostProcessors保存此时,只有三个BeanFactoryPostProcessor实现

类,但是只有前两个是实现了BeanDefinitionRegistryPostProcessor接口。
A. CachingMetadataReaderFactoryPostProcessor
注册SharedMetadataReaderFactoryBean工厂bean,其实现了FactoryBean接口,主要用于在类路径下class文件扫描时读取类信息,相关类: SimpleMetadataReader, ClassPathScanningCandidateComponentProvider

B. ConfigurationWarningsPostProcessor
用于对启动类上设置的扫描包进行验证,用户设置的扫描包不能是: org.springframework和org,否则抛出异常.

C. PropertySourceOrderingPostProcessor
PropertySourceOrderingPostProcessor仅实现了BeanFactoryPostProcessor,目的将ConfigurableEnvironment中的名称为”defaultProperties”的PropertySource放在集合最后

通过beanFactory.getBeanNamesForType(…)获取Spring容器中实现BeanDefinitionRegistryPostProcessor接口的类名称集合并遍历,如果bean同时是PriorityOrdered接口的实现类,则通过getBean()获取实例对象,此时容器中只有一个ConfigurationClassPostProcessor,主要用于类路径下文件扫描.

调用ConfigurationClassPostProcessor实现的postProcessBeanDefinitionRegistry()方法,开始执行类路径扫描。通过SimpleMetadataReader指定包下的class文件,如果扫描到的类是一个配置类,或者是通过@Import注解导入的类会采用递归的方式继续判断是否是配置类,直到是解析到普通的Bean,然后通过this.reader.loadBeanDefinitions(configClasses),过滤得到符合条件注解要求的BeanDefinition

因为执行完类路径扫描后,可能有实现BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor接口的Bean,所以需要再次通过beanFactory.getBeanNamesForType(…)获取Spring中实现BeanDefinitionRegistryPostProcessor接口的类名称集合,去除已经调用过的实现类ConfigurationClassPostProcessor,遍历bean名称获取实现了Ordered接口的实例,排序后回调接口方法

在while(reiterate) 中遍历调用没有实现排序接口BeanDefinitionRegistryPostProcessor的bean。

为什么要用while语句? 为了防止在回调方法中注入一个新的BeanDefinitionRegistryPostProcessor实现类.这样可以调用新的BeanDefinitionRegistryPostProcessor

回调BeanDefinitionRegistryPostProcessor父类BeanFactoryPostProcessor的方法postProcessBeanFactory(beanFactory) 无排序

获取BeanFactoryPostProcessor接口实现类,按照排序接口类型分类排序,回调接口方法

遍历执行实现org.springframework.core.PriorityOrdered排序的BeanFactoryPostProcessor遍历执行实现org.springframework.core.Ordered排序的BeanFactoryPostProcessor遍历执行未实现排序接口的BeanFactoryPostProcessor 2.4 注册BeanPostProcessors用于处理bean

通过beanFactory.getBeanNamesForType(…)获取BeanPostProcessor类型的beanName集合

遍历beanNames,按照排序接口类型分类并排序,如果是MergedBeanDefinitionPostProcessor实现类,也将独立保存到一个集合中,这接口主要用于Spring内部使用.最后得到如下三个集合,通过abstractBeanFactory.addBeanPostProcessor(postProcessor)保存BeanPostProcessor

添加ApplicationListenerDetector,用于收集事件监听器实现类,将其添加到AbstractApplicationContext的applicationListeners集合中

注意点: 注册BeanPostProcessor时,会调用getBean(beanName)获取BeanPostProcessor实例对象,而getBean()方法内部又会调用已经存在的BeanPostProcessor处理新创建的Bean,因此先注册的BeanPostProcessor可能会处理后注册的BeanPostProcessor,例如:
实现PriorityOrdered接口的BeanPostProcessor会处理后注册的实现Ordered的BeanPostProcessor
实现Ordered接口的BeanPostProcessor会处理后注册的没有实现排序接口的BeanPostProcessor

2.5 注册事件广播器到Spring容器

initApplicationEventMulticaster()方法通过beanFactory.registerSingleton()向Spring容器注册事件广播器,用于广播事件

2.6 注册事件监听器

用于加载开发者通过注解配置的监听器,只能监听ContextRefreshedEvent之后的事件

2.7 完成所有非懒加载Bean的实例化

finishBeanFactoryInitialization(beanFactory);主要通过获取所有beanName,遍历通过AbstractBeanFactory.getBean(name)方法完成bean的创建. 所有的bean完成实例化之后,重新遍历bean实例,查找实现SmartInitializingSingleton接口的bean,回调接口方法。

2.8 发布ContextRefreshedEvent事件

ContextRefreshedEvent事件在ApplicationStartedEvent和ApplicationReadyEvent事件之前发布。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。