免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
はじめに:いつもラフな理解を持ってBeanを作成し、初期化するためにSpringコンテナ上のさまざまな情報を読み取るために、今日の時間を取ることによって、次の初期化SpringコンテナとBeanの作成プロセスについての詳細を学びたいと思いました。
Springコンテナの初期化処理(ノート)
:AnnotationConfigApplicationContext例に
見るの継承グラフ:
ソースコード解析AnnotationConfigApplicationContext
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(UserConfig.class);
メインコードをAnnotationConfigApplicationContex
public AnnotationConfigApplicationContext(Class... annotatedClasses) {
this();
//2.注册bean配置类
this.register(annotatedClasses);
//3.刷新上下文
this.refresh();
}
1.この()スキャナ及びリーダ豆を初期化します
public AnnotationConfigApplicationContext() {
//在IOC容器中初始化一个 注解bean读取器AnnotatedBeanDefinitionReader
this.reader = new AnnotatedBeanDefinitionReader(this);
//在IOC容器中初始化一个 按类路径扫描注解bean的 扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
2.レジスタ(annotatedClasses)
タイプコンフィギュレーションレジスタ豆、豆AnnotationConfigApplicationContextコンテナ実装ノートregisterBean AnnotatedBeanDefinitionReader方法を渡す読み取り、特に次のソース:AnnotationConfigApplicationContext.javaレジスタ法
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null);
}
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//将Bean配置类信息转成容器中AnnotatedGenericBeanDefinition数据结构, AnnotatedGenericBeanDefinition继承
//自BeanDefinition作用是定义一个bean的数据结构,下面的getMetadata可以获取到该bean上的注解信息
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
//@Conditional装配条件判断是否需要跳过注册
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
//解析bean作用域(单例或者原型),如果有@Scope注解,则解析@Scope,没有则默认为singleton
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//作用域写回BeanDefinition数据结构, abd中缺损的情况下为空,将默认值singleton重新赋值到abd
abd.setScope(scopeMetadata.getScopeName());
//生成bean配置类beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//通用注解解析到abd结构中,主要是处理Lazy, primary DependsOn, Role ,Description这五个注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
//如果配置@Primary注解,则设置当前Bean为自动装配autowire时首选bean
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
//设置当前bean为延迟加载
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
//其他注解,则添加到abd结构中
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
//根据beanName和bean定义信息封装一个BeanDefinitionHolder,其实就是一个 beanname和BeanDefinition的映射
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//创建代理对象 借助AnnotationConfigUtils工具类解析通用注解
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// new ConcurrentHashMap<String, BeanDefinition>(256);用于保存注bean定义信息(beanname 和 beandefine映射)注册到IOC容器中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
目的:コンフィグレーションBeanクラス自体の解決と登録を完了します。コンテナIOCキーと値のペアの形でそれを保存します。
3リフレッシュ()の更新状況
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1.刷新前的预处理
prepareRefresh();
// 2.获取刷新后的内部Bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3.BeanFactory的预准备工作
prepareBeanFactory(beanFactory);
try {
// BeanFactory准备工作完成后,可以做一些后置处理工作
//4.空方法,用于在容器的子类中扩展
postProcessBeanFactory(beanFactory);
// 5. 执行BeanFactoryPostProcessor的方法,BeanFactory的后置处理器
//在BeanFactory标准初始化之后执行的
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册BeanPostProcessor(Bean的后置处理器),用于拦截bean创建过程
registerBeanPostProcessors(beanFactory);
// 7. 初始化MessageSource组件(做国际化功能;消息绑定,消息解析).
initMessageSource();
// 8. 初始化事件派发器
initApplicationEventMulticaster();
//9.可以用于子类实现在容器刷新时自定义逻辑初始化
onRefresh();
// 10. 注册时间监听器,将ApplicationListener注册到容器中来
registerListeners();
// 11. 初始化所有剩下的单实例bean,单例bean在初始化容器时创建,懒加载在调用的时候创建
finishBeanFactoryInitialization(beanFactory);
//12. 完成BeanFactory的初始化创建工作,IOC容器就创建完成
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();
}
}
}
豆の作成プロセスの方法でリフレッシュ文脈語方法1-12、第11回を更新します。創造豆の具体的な方法は、我々は記事を参照することができ、コンテナの初期化プロセスとソースコード解析|春