前面文章已经介绍如何自己实现一个简单的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();
}
}
}