1. 要分析的代码

public static void main(String[] args)
{
//创建ApplicationContext
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopConfig.class);
//从ApplicationContext中获取Calc的bean
Calc calc = applicationContext.getBean(Calc.class);
//调用div方法
System.out.println(calc.div(10,10)); }

分成创建ApplicationContext和从ApplicationContext中获取Calc的bean这两个过程,我们一步步跟踪

2. 创建ApplicationContext

2.1. AnnotationConfigApplicationContext构造方法

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//调用无参构造方法
this();
//注册主配置类
register(annotatedClasses);
//刷新ioc容器
refresh();
}

refresh方法用于刷新容器,这是我们分析的重点,他会调用AnnotationConfigApplicationContext的父类AbstractApplicationContext的refresh方法。

2.2. 刷新ioc容器

  • AbstractApplicationContext refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//解析占位符属性
prepareRefresh(); // Tell the subclass to refresh the internal bean factory.
//获取bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context.
//为bean工厂初始化一些属性,加入一些BeanPostProcessor
prepareBeanFactory(beanFactory); try {
// Allows post-processing of the bean factory in context subclasses.
//在bean工厂创建完后做一些事情。留给子类实现(模板方法)
postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context.
//按优先级顺序调用BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation.
//把所有BeanPostProcessor注册到bean工厂
registerBeanPostProcessors(beanFactory); // Initialize message source for this context.
//初始化国际化相关的bean
initMessageSource(); // Initialize event multicaster for this context.
//初始化事件派发器
initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses.
//留给子类实现(模板方法)
onRefresh(); // Check for listener beans and register them.
//注册事件监听器到事件派发器中
registerListeners(); // Instantiate all remaining (non-lazy-init) singletons.
//实例化所有剩下的非懒加载的单例
finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event.
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
} // Destroy already
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();
}
}
}

2.2.1. 准备刷新

  • AbstractApplicationContext prepareRefresh
protected void prepareRefresh() {
// 启动时间,active标志
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true); if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
} // Initialize any placeholder property sources in the context environment.
//初始化占位符属性。模板方法(留给子类实现)
initPropertySources(); // Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
//校验属性
getEnvironment().validateRequiredProperties(); // Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
//保存早期的事件。后面用于事件分发
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}

准备刷新的工作没什么说的,如注释。其中initPropertySources这个初始化占位符属性的操作留给子类实现

2.2.2. 获取刷新后的BeanFactory

  • AbstractApplicationContext obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新bean工厂。模板方法(留给子类实现)
refreshBeanFactory();
//获取bean工厂并且返回--什么时候创建的?
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}

refreshBeanFactory这个刷新BeanFactory的操作又是留给子类实现

2.2.3. 准备BeanFactory

  • AbstractApplicationContext prepareBeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//设置类加载器等
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks.
//为bean工厂加入PostProcessor:ApplicationContextAwareProcessor->用于ApplicationContextAware,忽略一些依赖等
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
//
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners.
//为bean工厂加入PostProcessor:ApplicationListenerDetector--用于事件监听
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found.
//为bean工厂加入PostProcessor:LoadTimeWeaverAwareProcessor--用于切面
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
} // Register default environment beans.
//注册环境相关的beans
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}

这个准备就是往BeanFactory中注入一些PostProcessor

2.2.4. 调用BeanFactoryPostProcessor的postProcess方法

  • AbstractApplicationContext invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//把当前bean工厂,所有的bean工厂PostProcessors传入
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

这个操作比较关键,详见2.调用BeanFactoryPostProcessor的postProcess方法.md

2.2.5. 注册BeanPostProcessor

  • AbstractApplicationContext registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//传入当前bean工厂
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

这个操作比较关键,详见下面的3.注册BeanPostProcessor.md

2.2.6. 初始化国际化相关的bean

  • initMessageSource
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//从bean工厂中获取messageSource
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
//获取不到的话
else {
// Use empty MessageSource to be able to accept getMessage calls.
//创建一个默认的DelegatingMessageSource
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
//并注册进入bean工厂
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}

2.2.7. 初始化事件派发器

  • initApplicationEventMulticaster
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//从bean工厂中获取名为applicationEventMulticaster的bean(事件派发器)
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
//获取不到
else {
//创建一个SimpleApplicationEventMulticaster并注册进bean工厂
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}

2.2.8. 注册事件监听器到事件派发器中

  • registerListeners
protected void registerListeners() {
// Register statically specified listeners first.
//获取所有的事件监听器,放入事件派发器中
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
} // Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
//从bean工厂中获取类型为ApplicationListener的所有bean,放入事件派发器中
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
} // Publish early application events now that we finally have a multicaster...
//获取早期的事件,使用事件派发器分派
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}

2.2.9. 完成BeanFactory的初始化

  • finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
} // Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
} // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
} // Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons.
//实例化所有剩下的非懒加载的单实例bean
beanFactory.preInstantiateSingletons();
}

这个步骤中尤其重要,他的preInstantiateSingletons会实例化所有非懒加载的单实例bean,详见4.实例化所有非懒加载的单实例bean.md

2.2.10. 完成刷新

  • finishRefresh
protected void finishRefresh() {
// Initialize lifecycle processor for this context.
//初始化生命周期有关的PostProcessor
initLifecycleProcessor(); // Propagate refresh to lifecycle processor first.
//调用刚刚的LifecycleProcessor的onRefresh方法
getLifecycleProcessor().onRefresh(); // Publish the final event.
//发布ContextRefreshedEvent事件
publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
2.2.10.1. 初始化生命周期有关的PostProcessor
  • initLifecycleProcessor
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//获取LifecycleProcessor
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isDebugEnabled()) {
logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
//没有创建默认的并注册进ioc
else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate LifecycleProcessor with name '" +
LIFECYCLE_PROCESSOR_BEAN_NAME +
"': using default [" + this.lifecycleProcessor + "]");
}
}
}

7.Java Spring框架源码分析-IOC-创建spring容器的更多相关文章

  1. 干货分享之spring框架源码分析02-(对象创建or生命周期)

    记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新.欢迎大家指正! 环境: spring5.X + idea 之前分析了Spring读取xml文件的所有信息封装成beanDef ...

  2. 精尽Spring Boot源码分析 - 内嵌Tomcat容器的实现

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  3. 精尽Spring Boot源码分析 - 支持外部 Tomcat 容器的实现

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  4. 设计模式(五)——原型模式(加Spring框架源码分析)

    原型模式 1 克隆羊问题 现在有一只羊 tom,姓名为: tom, 年龄为:1,颜色为:白色,请编写程序创建和 tom 羊 属性完全相同的 10 只羊. 2 传统方式解决克隆羊问题 1) 思路分析(图 ...

  5. Java集合框架源码分析(2)LinkedList

    链表(LinkedList) 数组(array)和数组列表(ArrayList)都有一个重大的缺陷: 从数组的中间位置删除一个元素要付出很大的代价,因为数组中在被删除元素之后的所有元素都要向数组的前端 ...

  6. 精尽Spring Boot源码分析 - 文章导读

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  7. spring源码分析系列 (3) spring拓展接口InstantiationAwareBeanPostProcessor

    更多文章点击--spring源码分析系列 主要分析内容: 一.InstantiationAwareBeanPostProcessor简述与demo示例 二.InstantiationAwareBean ...

  8. 精尽Spring MVC源码分析 - WebApplicationContext 容器的初始化

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  9. 精尽Spring Boot源码分析 - SpringApplication 启动类的启动过程

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  10. 精尽Spring Boot源码分析 - 剖析 @SpringBootApplication 注解

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

随机推荐

  1. 【Linux】U-Boot 加载并启动 Linux 系统程序

    U-Boot 加载并启动 Linux 系统程序 零.介绍 最近在玩一些嵌入式的开发板,在引导操作系统时需要用到U-Boot,故此研究一下. U-Boot(Universal Bootloader)是一 ...

  2. Global.asax 转

    备忘: 项目中的Global.asax文件里通常包含这5个方法: Application_Start – web 应用程序最初启动时执行 Application_End – 应用程序关闭时运行 App ...

  3. hexo搭建博客记录

    这是一次hexo搭建博客并引入archer主题的使用记录. 环境准备 首先是hexo工具的安装使用,这个工具是依赖于nodejs的一个命令行工具,并且各种使用也依赖于node生态,所以需要先进行nod ...

  4. 使用注解的方式编写:@Aspect运用

    列子. public interface Calculator { // 加 public int add(int i,int j); // 减 public int sub(int i,int j) ...

  5. 线上救急-AWS限频

    线上救急-AWS限频 问题 在一个天气炎热的下午,我正喝着可口可乐,悠闲地看着Cursor生成代码,忽然各大群聊中出现了加急@全体的消息,当时就心里一咯噔,点开一看,果然,线上服务出问题,多个能源统计 ...

  6. Asp.net core 少走弯路系列教程(五)HTTP 协议学习

    前言 新人学习成本很高,网络上太多的名词和框架,全部学习会浪费大量的时间和精力. 新手缺乏学习内容的辨别能力,本系列文章为新手过滤掉不适合的学习内容(比如多线程等等),让新手少走弯路直通罗马. 作者认 ...

  7. Python3爬虫批量爬取图片并保存到本地

    看新闻的时候忽然发现了一个图片网站,那肯定得爬一下. 网址:https://www.0xu.cn/ 不难发现,qcmn这个路径对应青春美女 右键检查图片地址可见 访问该地址成功访问到了图片 正式开始 ...

  8. Spring AOP面向切面编程 通知类型

    Spring AOP面向切面编程 通知类型 通知分为: 前置通知 执行方法之前通知 后置通知 执行方法之后通知 异常通知 相当于cache里面的内容 最终通知 相当于finally 环绕通知 前四种通 ...

  9. 工具 | webshell-decryptor

    0x00 简介 webshell-decryptor是一款通过获取到的webshell流量.url.key来还原攻击者使用webshell所做操作的工具. 下载地址: webshell-decrypt ...

  10. Oracle、MySQL、SQL Server、PostgreSQL、Redis 五大数据库的区别

    以下是 Oracle.MySQL.SQL Server.PostgreSQL.Redis 五大数据库的对比分析,从用途.数据处理方式.高并发能力.优劣势等维度展开: 一.数据库分类 数据库 类型 核心 ...