文章目录
- spring-系列
- 前言
- 源码分析
- AnnotationConfigApplicationContext
- refresh()
- invokeBeanFactoryPostProcessors(beanFactory)
- finishBeanFactoryInitialization(beanFactory)
- getBean(beanName)
- 总结
前言
spring生命周期是spring IOC的管理过程。本文主要是针对spring有一定了解的读者,如果还不知道什么是spring建议先去官方(spring官网)学习,由于spring源码非常复杂,本文通过主流程的方式来解读源码。想详细了解spring原理请关注博主的spring系列文章。
源码分析本文从源码的角度分析spring从加载到生成Bean的整个生命周期,废话不多说直接上源码:
@Configuration public class TestConfig { @Bean public String name() { return "Hello Spring."; } } public class TestMain { public static void main(String[] args) { // 创建SpringIOC容器 ApplicationContext acx = new AnnotationConfigApplicationContext(TestConfig.class); // 通过Bean名称获取Bean Object name = acx.getBean("name"); System.out.println(name); } }
- AnnotationConfigApplicationContext是通过注解方式加载Bean的实现来,本文从这个类入口。
- getBean(beanName) 通过Bean名称获取Bean对象
public AnnotationConfigApplicationContext() { StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create"); // AnnotatedBeanDefinition的解析器 this.reader = new AnnotatedBeanDefinitionReader(this); createAnnotatedBeanDefReader.end(); // 类路劲下扫描Bean的扫描器 this.scanner = new ClassPathBeanDefinitionScanner(this); } public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); } public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; this.conditionevaluator = new Conditionevaluator(registry, environment, null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } public AnnotationConfigApplicationContext(Class>... componentClasses) { this(); register(componentClasses); refresh(); }
- 第一步:初始化BeanFactory = new DefaultListableBeanFactory()
- 第二步:初始化AnnotatedBeanDefinition的解析器this.reader = new AnnotatedBeanDefinitionReader(this)
- 第三步:执行AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)加载内部逻辑处理器Bean BeanFactoryPostProcessor
- 第四步:初始化Bean扫描器 this.scanner = new ClassPathBeanDefinitionScanner(this)
- 第五步:执行register(componentClasses) 将当前配置类componentClasses注册为AnnotatedBeanDefinition对象。
- 第六步:执行refresh() 刷新Bean的加载逻辑(根据前5步来加载Bean),是spring中最核心的方法
// 刷新Bean的加载逻辑 @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); beanPostProcess.end(); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // 出现异常销毁Bean destroyBeans(); // 重置'active' 标志. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); contextRefresh.end(); } } }
加载Bean执行逻辑:
- prepareRefresh() 准备上下文刷新工作,如设置初始值
- obtainFreshBeanFactory() 告诉子类刷新内部beanFactory,返回BeanFactory
- prepareBeanFactory(beanFactory) 准备beanFactory,以便于上下文中使用
- postProcessBeanFactory(beanFactory) 允许在上下文子类中对bean后置处理器的处理(BeanFactoryPostProcessor)
- invokeBeanFactoryPostProcessors(beanFactory) 执行相关的BeanFactoryPostProcessory后置处理器
- registerBeanPostProcessors(beanFactory) 注册的bean处理器(BeanPostProcessors)
- initMessageSource() 初始化MessageSource
- initApplicationEventMulticaster() 初始化Application监听器的管理Bean(ApplicationEventMulticaster)
- onRefresh() 刷新子类的Bean加载 *** 作
- registerListeners() 检查和注册监听器
- finishBeanFactoryInitialization(beanFactory) 实例化所有(非懒加载)单例Bean(默认就是单例)
- finishRefresh() 发布相应的事件
- destroyBeans() 销毁Bean
到这里Bean整个生命周期就执行完成了。其中invokeBeanFactoryPostProcessors(beanFactory) 和finishBeanFactoryInitialization(beanFactory) 方法是整个流程的核心,下面对他们详细分析。
invokeBeanFactoryPostProcessors(beanFactory)在执行nvokeBeanFactoryPostProcessors(beanFactory)方法之前都是做准备工作,该方法是执行对已加载的Bean的BeanFactoryPostProcessory类型对象进行调用,换句话说:该方法就是加载所有满足Bean条件的java类,将其解析为BeanDefinition对象注册到beanFactory。由于该方法逻辑比较复杂单独用一篇博文来讲解,请移步。
finishBeanFactoryInitialization(beanFactory)该方法是对单例Bean的进行初始化,直接上源码:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 初始化service类型转换器. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // 尽早初始化LoadTimeWeaverAware bean,以便尽早注册其转换器。 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }
beanFactory.preInstantiateSingletons() 是真正执行加载Bean的逻辑
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. ListbeanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean> factory = (FactoryBean>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction ) ((SmartFactoryBean>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { getBean(beanName); } } }
根据源码发现最终都是通过执行getBean(beanName)来初始化Bean。
getBean(beanName)该方法是spring中重要的方法之一,主要功能如下:
- 通过beanName查询BeanDefinition对象。
- 通过BeanDefinition创建出Bean实例instance,如果该实例构造函数中需要注入Bean也在该步骤完成
- 通过实例进行反向依赖注入 ,针对属性值和set方法注入
- 执行初始化方法,和BeanPostProcessors
- 返回Bean实例对象,如果是单例则缓存Bean
由于该方法代码实现非常复杂,博主将用一篇文章详细讲解,请移步。
总结根据源码分析spring的生命周期包含注册Bean和实例化Bean两大阶段:
第一阶段:注册Bean
1. 初始化spring上下文包括,BeanFactory,扫描器,BeanDefinition解析器等
2. 加载当前定义的Bean和内部Bean
3. 执行BeanFactoryPostProcessor接口,查询所有满足Bean的java对象,将其转换为BeanDefinition对象注册到BeanFactory中
4. 根据已加载的Bean寻找所有BeanPostProcessors对象注册到BeanFactory中
5. 初始化上下文资源MessageSource
6. 注册监听器
7. 初始化单例Bean
8. 出发相关事件
第二阶段:实例化Bean
1. 通过BeanDefinition创建出Bean实例instance,如果该实例构造函数中需要注入Bean也在该步骤完成
2. 执行@PostConstruct的方法
3. 通过实例进行反向依赖注入 ,针对属性值和set方法注入
4. 执行BeanAware的相关接口,初始化方法,和BeanPostProcessors
5. 返回Bean实例对象,如果是单例则缓存Bean
6. 销毁Bean
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)