Spring容器启动初始化步骤简单介绍

前面文章已经介绍如何自己实现一个简单的springIoc容器。那么下面来了解spring是如何做的。

Spring的启动主要包括register()  注册配置类 BeanDefinition 到容器 和 refresh()加载或者刷新容器中的Bean 两个步骤。

AnnotationConfigApplicationContext
	/**
	 * Create a new AnnotationConfigApplicationContext with the given DefaultListableBeanFactory.
	 * @param beanFactory the DefaultListableBeanFactory instance to use for this context
	 */
	public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {
		super(beanFactory);
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
	/**
	 * Create a new AnnotationConfigApplicationContext, deriving bean definitions
	 * from the given annotated classes and automatically refreshing the context.
	 * @param annotatedClasses one or more annotated classes,
	 * e.g. {@link Configuration @Configuration} classes
	 */
	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		this();
		register(annotatedClasses);
		refresh();
	}

一、register步骤 主要 将 是beanDefinitionMap.put(beanName, beanDefinition);

也就是将beanDefinition放入beanDefinitionMap中。具体代码如下:

AnnotatedBeanDefinitionReader
	/**
	 * Register one or more annotated classes to be processed.
	 * <p>Calls to {@code register} are idempotent; adding the same
	 * annotated class more than once has no additional effect.
	 * @param annotatedClasses one or more annotated classes,
	 * e.g. {@link Configuration @Configuration} classes
	 */
	public void register(Class<?>... annotatedClasses) {
		for (Class<?> annotatedClass : annotatedClasses) {
			registerBean(annotatedClass);
		}
	}

最终通过DefaultListableBeanFactory

	//---------------------------------------------------------------------
	// Implementation of BeanDefinitionRegistry interface
	//---------------------------------------------------------------------

	@Override
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}

		BeanDefinition oldBeanDefinition;

		oldBeanDefinition = this.beanDefinitionMap.get(beanName);
		if (oldBeanDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
						"': There is already [" + oldBeanDefinition + "] bound.");
			}
			else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (this.logger.isWarnEnabled()) {
					this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							oldBeanDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(oldBeanDefinition)) {
				if (this.logger.isInfoEnabled()) {
					this.logger.info("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + oldBeanDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (this.logger.isDebugEnabled()) {
					this.logger.debug("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + oldBeanDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					if (this.manualSingletonNames.contains(beanName)) {
						Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
						updatedSingletons.remove(beanName);
						this.manualSingletonNames = updatedSingletons;
					}
				}
			}
			else {
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				this.manualSingletonNames.remove(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (oldBeanDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}

二、refresh()方法

加载或者刷新容器中的Bean  。AbstractApplicationContext中refresh()源码

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// 1. 刷新前的预处理
		prepareRefresh();
 
		// 2. 获取 beanFactory,即前面创建的【DefaultListableBeanFactory】
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
		// 3. 预处理 beanFactory,向容器中添加一些组件
		prepareBeanFactory(beanFactory);
 
		try {
			// 4. 子类通过重写这个方法可以在 BeanFactory 创建并与准备完成以后做进一步的设置
			postProcessBeanFactory(beanFactory);
 
			// 5. 执行 BeanFactoryPostProcessor 方法,beanFactory 后置处理器
			*在BeanFactory标准初始化之后执行每个BeanFactoryPostProcessor
			实现类的postProcessBeanFactory,
			值得注意的是ConfigurationClassPostProcessor就是在这里执行的
			将我们通过注解配置的Bean解析成BeanDefinition并注册到容器中*
			invokeBeanFactoryPostProcessors(beanFactory);
 
			// 6. 注册 BeanPostProcessors,bean 后置处理器
			*这一步是向容器中注册BeanPostProcessor(会通过其BeanDefinition创建出Bean,然后让
			beanFactory统一进行管理),
			BeanPostProcessor会干预 Spring 初始化 bean 的流程,从而完成代理、自动注入等各种功能。
			同样也存在顺序上的问题:先注册实现了PriorityOrdered接口的BeanPostProcessor,
			然后是实现了Ordered接口的,然后是剩下所有的普通的BeanPostProcessor,
			最后还会将实现了MergedBeanDefinitionPostProcessor接口
			的BeanPostProcessor再注册一遍。*		    	  
			registerBeanPostProcessors(beanFactory);
 
			// 7. 初始化 MessageSource 组件(做国际化功能;消息绑定,消息解析)
			初始化 MessageSource 组件,做国际化的处理。
			initMessageSource();
 
			// 8. 初始化事件派发器,在注册监听器时会用到
			初始化事件广播器,如果用户配置了就用自定义的,如果没有就创建一个SimpleApplicationEventMulticaster
			initApplicationEventMulticaster();
 
			// 9. 留给子容器(子类),子类重写这个方法,在容器刷新的时候可以自定义逻辑,web 场景下会使用
			onRefresh();
 
			// 10. 注册监听器,派发之前步骤产生的一些事件(可能没有)
		将容器中所有的ApplicationListener都注册到容器中,由容器统一管理。
然后通过事件广播器发布之前步骤产生的事件ApplicationEvent。
			registerListeners();
 
			// 11. 初始化所有的非单实例 bean
			初始化剩下所有的非懒加载的单例Bean对象,具体来说就是遍历所有的beanName,然后调用getBean(beanName)方法来创建Bean对象。值得注意的是,如果该Bean是FactoryBean类型,会调用两次getBean方法,第一次是将其当作普通Bean来创建,第二次是将其当作工厂,通过它来创建对象。
			getBean的流程请参考这篇文章:https://blog.csdn.net/zhang_qing_yun/article/details/120083309
				finishBeanFactoryInitialization(beanFactory);
 
			// 12. 发布容器刷新完成事件
			首先初始化生命周期处理器,如果用户没有配置则提供一个默认的DefaultLifecycleProcessor。然后发布容器刷新完毕的事件。
			finishRefresh();
		}
		
		...
		
		finally {
			// Reset common introspection caches in Spring's core, since we
			// might not ever need metadata for singleton beans anymore...
			清空启动过程中产生的一些缓存,例如:反射相关的信息、注解相关的信息、类加载器相关的信息等,因为不再需要单例Bean的元数据了。
			resetCommonCaches();
		}
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值