Spring注解版源码分析(三)
前言
这篇主要分析register方法和refresh方法
register方法分析
通过对register方法不断调入,会进入这个核心方法,具体步骤就不贴了。
这个方法主要是注册一个bean从一个指定的bean类,从类的注解中获取它的metadata。
首先分析下AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
什么是AnnotatedGenericBeanDefinition呢?
老样子,先看下类图
其中比较重要的就是BeanDefinition重点分析下
parentName父类定义名称
beanClassName分类定义类名称
scope是否单例
lazyInit懒加载
dependsOn依赖的bean定义,spring保证依赖的bean先创建
autowireCandidate是否可以被别的bean自动注解
primary是否首先,主要通过type刷选出多个会用到
factoryBeanName、factoryMethodName和工厂方法创建bean相关
而对于AnnotatedGenericBeanDefinition,其中除了和BeanDefinition相关之外还有一个Metadata主要是和解析注解相关。
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
完成一些通用的Bean定义属性设置
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
主要是将我们的beandefinition放到一个map中,这个map是ConcurrentHashMap类型
refresh方法分析
Spring最重要的方法来了
// An highlighted block
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 刷新的一些准备工作,设置一些状态,刷选的时间、是否关闭、是否激活
prepareRefresh();
//获取BeanFactory;默认实现是DefaultListableBeanFactory,在创建容器的时候创建的
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加载器,BeanPostProcessor和XXXAware自动装配等)
prepareBeanFactory(beanFactory);
try {
//BeanFactory准备工作完成后进行的后置处理工作
postProcessBeanFactory(beanFactory);
//执行BeanFactoryPostProcessor的方法;
invokeBeanFactoryPostProcessors(beanFactory);
//注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行
registerBeanPostProcessors(beanFactory);
//初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
initMessageSource();
//初始化事件派发器
initApplicationEventMulticaster();
//子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器
onRefresh();
//注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的
registerListeners();
//初始化所有剩下的非懒加载的单例bean
finishBeanFactoryInitialization(beanFactory);
//完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
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();
}
}
}
``后面详细分析各个方法