Spring启动流程之DefaultListableBeanFactory

一句话总结
Spring的启动主要包括初始化和refresh()两个步骤!

初始化
// 初始化容器
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    // 注册 Spring 内置后置处理器的 BeanDefinition 到容器
    this();
    // 注册配置类 BeanDefinition 到容器
    register(annotatedClasses);
    // 加载或者刷新容器中的Bean
    refresh();
}

public AnnotationConfigApplicationContext() {
	this.reader = new AnnotatedBeanDefinitionReader(this);
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

流程总结

  1. 调用父类构造器,创建了DefaultListableBeanFactory。
  2. 调用自己的this()方法,创建了两个对象AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner:
  • AnnotatedBeanDefinitionReader是注解配置读取器。在进行该对象创建时,会向容器中添加6个BeanDefinition,其中有两个比较重要:ConfigurationClassPostProcessor(一个BeanFactoryPostProcessor,用于将配置类中的Bean的BeanDefinition注册到容器中,同时@Import、@ComponentScan等注解也是在这里做的处理)、AutowiredAnnotationBeanPostProcessor(一个BeanPostProcessor,用于处理@Autowired的自动注入,例如当creatBean时调用构造器通过反射实例化对象时,如果使用了@Autowired就会进行自动注入)。
  • ClassPathBeanDefinitionScanner是路径扫描器,用于对指定的包目录进行扫描查找 bean 对象,然后为其创建BeanDefinition对象并进行注册。在创建这个对象时,会创建默认的过滤器(如:添加了注解类型的过滤器AnnotationTypeFilter(Component.class)),使得在进行包扫描的时候将指定条件的类的BeanDefinition添加到容器中,而对其它的类不这么干。
  1. 调用AnnotatedBeanDefinitionReader的register方法将用户传入的 Spring 配置类解析成一个 BeanDefinition 然后注册到容器中。
refresh函数
  • 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都注册到容器中,由容器统一管理。
然后通过事件广播器发布之前步骤产生的事件ApplicationEventregisterListeners();
 
			// 11. 初始化所有的非单实例 bean
			初始化剩下所有的非懒加载的单例Bean对象,具体来说就是遍历所有的beanName,然后调用getBean(beanName)方法来创建Bean对象。值得注意的是,如果该BeanFactoryBean类型,会调用两次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. https://blog.csdn.net/zhang_qing_yun/article/details/120157047

你可能感兴趣的:(spring,spring,java)