这篇文章主要讲解 IOC 容器的创建过程,让大家对整体有一个全局的认识,文章目录如图:

1. 基础知识

1.1 什么是 Spring IOC ?

IOC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。

传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试。

有了 IOC 容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,便于测试和功能复用,整个体系结构更加灵活。

理解 IOC 的关键是要明确 “谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,我们浅析一下:

  • 谁控制谁,控制什么

    • 传统 Java SE 程序设计,我们直接在对象内部通过 new 进行创建对象,是程序主动去创建依赖对象;

    • IOC 是有专门一个容器来创建这些对象,即由 IOC 容器来控制对象的创建;

    • 谁控制谁?当然是 IOC 容器控制了对象;

    • 控制什么?主要控制了外部资源获取。

  • 为何反转,哪些方面反转

    • 传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;

    • 反转则是由容器来帮忙创建及注入依赖对象;

    • 为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;

    • 哪些方面反转了?依赖对象的获取被反转了。

1.2 容器创建过程

在看源码之前,首先搞清楚 Spring IOC 容器的创建过程,然后再深入源码。

IOC 容器如婚姻介绍所:

  • 男人 A 要求需要一个女人,中介从婚姻介绍所根据男人 A 给他介绍了如花;

  • 男人 B 要求介绍一个肤白貌美大长腿,中介从婚姻介绍所根据男人 B 给他介绍了女神。

从婚姻介绍所的例子可以大概知道 Spring IOC 是存储、定制、管理等功能的各种定制化的 bean 对象容器,下图是 Spring IOC 容器创建基本流程。

2. 核心知识

2.1 相关对象

2.1.1 ApplicationContext

ApplicationContext 接口是 BeanFactory 的子接口,也被称为 Spring 上下文,与 BeanFactory 一样,可以加载配置文件中定义的 bean,并进行管理。

它还加强了企业所需要的功能,如从属性文件中解析文本信息和将事件传递给所有指定的监视器,下图是 ApplicationContext 接口的继承关系。

ApplicationContext 接口主要的 5 个作用如表所示:

2.1.2 BeanDefinitionReader

// 示例
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

配置文件解析器,如将配置文件中的 bean 信息解析成对应的 BeanDefinition 对象。

xml 文件解析使用是就是BeanDefinitionReader 实现类 XmlBeanDefinitionReader。

2.1.3 BeanFactoryPostProcessor

可以修改 Spring 上下文中 BeanDefinition 信息。

如下图 BeanFactoryPostProcessor 的子类 PropertySourcesPlaceholderConfigurer 的作用可以为数据库连接池 ${} 占位符赋值等等。

2.1.4 BeanFactory

是所有 Bean 容器的根接口,定义了 spring 容器基本方法。

如使用 getBean(beanName,Class) 获取对象。

2.2 源码核心流程

容器初始化的核心源码,都在 refresh() 方法中:

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//1:准备刷新上下文环境prepareRefresh();//2:获取初始化Bean工厂ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//3:对bean工厂进行填充属性prepareBeanFactory(beanFactory);try {//4:Spring开放接口 留给子类去实现该接口postProcessBeanFactory(beanFactory);//5:调用我们的bean工厂的后置处理器invokeBeanFactoryPostProcessors(beanFactory);//6:注册我们bean后置处理器registerBeanPostProcessors(beanFactory);//7:初始化国际化资源处理器initMessageSource();//8:初始化事件多播器initApplicationEventMulticaster();//9:这个方法同样也是留个子类实现,其中springboot也是从这个方法进行tomcat的启动onRefresh();//10:把我们的事件监听器注册到多播器上registerListeners();//11:实例化所有的非懒加载的单实例beanfinishBeanFactoryInitialization(beanFactory);//12:最后刷新容器 发布刷新事件(Spring cloud eureka也是从这里启动的)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();}}}

思维导图如图:

3. 源码解析

下面主要对 refresh() 的 12 个流程进行讲解。

3.1 prepareRefresh()

准备刷新上下文环境:

protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);if (logger.isInfoEnabled()) {logger.info("Refreshing " + this);}/*** 初始化上下文环境*/initPropertySources();/*** 用来校验我们容器启动必须依赖的环境变量的值*/getEnvironment().validateRequiredProperties();/*** 创建一个早期事件监听器对象*/if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);}else {// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}/*** 创建一个容器用于保存早期待发布的事件集合 什么是早期事件了?* 就是我们的事件监听器还没有注册到事件多播器上的时候都称为早期事件*/this.earlyApplicationEvents = new LinkedHashSet<>();}

3.2 ConfigurableListableBeanFactory()

获取初始化的 Bean 的工厂:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {//刷新bean工厂()refreshBeanFactory();//返回之前容器准备工作的时候创建的的bean工厂也就是DefaultListableBeanFactory(很重要)ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;}
protected final void refreshBeanFactory() throws IllegalStateException {//由于BeanFactory只能刷新一次,多线程情况下可能导致线程安全问题,所有使用cas原子操作来保证if (!this.refreshed.compareAndSet(false, true)) {throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");}//指定Bean工厂的序列化Idthis.beanFactory.setSerializationId(getId());}

3.3 prepareBeanFactory()

对 Bean 工厂进行填充属性:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {//设置bean工厂的类加载器为当前application应用上下文的加载器beanFactory.setBeanClassLoader(getClassLoader());//为bean工厂设置SPEL表达式解析器对象StandardBeanExpressionResolverbeanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));//为我们的bean工厂设置了一个propertyEditor属性资源编辑器对象(用于后面的给bean对象赋值使用)beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));//注册ApplicationContextAwareProcessor后置处理器用来处理ApplicationContextAware接口的回调方法beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));/*** 当Spring将ApplicationContextAwareProcessor注册后,那么在invokeAwarelnterfaces方法中调用的Aware类已经不是普通的bean了 ,* 如ResourceLoaderAware、ApplicationEventPublisherAware、ApplicationContextAware等,那么当然需要在Spring做bean的依赖注入的时候忽略它们。* 这个就是ignoreDependencyInterface的作用*/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.class的解析依赖后,* 当bean的属性注入的时候,一旦检测到属性为BeanFactory类型便会将beanFactory的实例注入进去。*/beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);//注册了一个事件监听器探测器后置处理器接口beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));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()));}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());}}

3.4 postProcessBeanFactory()

Spring 开放接口留给子类去实现该接口,主要用来改变 BeanFactory。

比如给 BeanFactory 添加一些自己的 BeanPostProcessor(Bean的后置处理器)

3.5 invokeBeanFactoryPostProcessors()

调用我们的 bean 工厂的后置处理器,里面逻辑非常复杂,需要的同学可以和我联系,有详细讲解,就不扩展了。

3.6 registerBeanPostProcessors()

注册我们 bean 后置处理器:

/*** 往容器中注册了我们的bean的后置处理器* bean的后置处理器在什么时候进行调用?在bean的生命周期中* @param beanFactory* @param applicationContext*/public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {//去容器中获取所有的BeanPostProcessor的bean名称String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);/*** beanFactory.getBeanPostProcessorCount()获取的是已经添加在beanFactory的beanPostProcessors集合中的* postProcessorNames.length  beanFactory工厂中BeanPostProcessor个数 +1 又注册了BeanPostProcessorChecker的后置处理器*/int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));/*** 按照BeanPostProcessor实现的优先级接口来分离我们的后置处理器*///保存实现了priorityOrdered接口的List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();//容器内部的List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();//实现了我们ordered接口的List<String> orderedPostProcessorNames = new ArrayList<>();//实现了我们任何优先级的List<String> nonOrderedPostProcessorNames = new ArrayList<>();//循环我们的bean定义(BeanPostProcessor)for (String ppName : postProcessorNames) {//若实现了PriorityOrdered接口的if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//显示的调用getBean流程创建bean的后置处理器BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);//加入到集合中priorityOrderedPostProcessors.add(pp);//判断是否实现了MergedBeanDefinitionPostProcessorif (pp instanceof MergedBeanDefinitionPostProcessor) {//加入到集合中internalPostProcessors.add(pp);}}//判断是否实现了Orderedelse if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}//把实现了priorityOrdered注册到容器中sortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);//处理实现Ordered的bean后置处理器List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();for (String ppName : orderedPostProcessorNames) {//显示调用getBean方法BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);//加入到集合中orderedPostProcessors.add(pp);//判断是否实现了MergedBeanDefinitionPostProcessorif (pp instanceof MergedBeanDefinitionPostProcessor) {//加入到集合中internalPostProcessors.add(pp);}}//排序并且注册我们实现了Order接口的后置处理器sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// 实例化我们所有的非排序接口的List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();for (String ppName : nonOrderedPostProcessorNames) {//显示调用BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);//判断是否实现了MergedBeanDefinitionPostProcessorif (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}//注册我们普通的没有实现任何排序接口的registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);//注册MergedBeanDefinitionPostProcessor类型的后置处理器sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);//注册ApplicationListenerDetector应用监听器探测器的后置处理器beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}

3.7 initMessageSource()

初始化国际化资源处理器:

/*** Initialize the MessageSource.* Use parent's if none defined in this context.*/protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();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 dms = new DelegatingMessageSource();dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;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 + "]");}}}

3.8 initApplicationEventMulticaster()

初始化事件多播器:

/*** 从bean工厂中获取或者直接显示的new一个事件多播器赋值给applicatoinContext对象的applicationEventMulticaster属性* 事件多播器采用典型的设计模式就是观察者模式 多播器作为的是一个被观察者* @see org.springframework.context.event.SimpleApplicationEventMulticaster*/protected void initApplicationEventMulticaster() {//获取我们的bean工厂对象ConfigurableListableBeanFactory beanFactory = getBeanFactory();//判断容器中是否包含了applicationEventMulticaster事件多播器组件if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {//直接显示的调用我们的getBean获取出来赋值给我们的applicationContext对象this.applicationEventMulticaster =beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);if (logger.isDebugEnabled()) {logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");}}//容器中没有的话else {//直接new一个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 + "]");}}}

3.9 onRefresh()

这个方法很重要,同样也是留个子类实现,其中 Spring Boot 就是从这个方法进行 tomcat 的启动。

3.10 registerListeners()

把我们的事件监听器注册到事件多播器上:

protected void registerListeners() {//获取容器中所有的监听器对象for (ApplicationListener<?> listener : getApplicationListeners()) {//把监听器挨个的注册到我们的事件多播器上去getApplicationEventMulticaster().addApplicationListener(listener);}//获取bean定义中的监听器对象String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);//把监听器的名称注册到我们的事件多播器上for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}//在这里获取我们的早期事件Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (earlyEventsToProcess != null) {//通过多播器进行播发早期事件for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}}

如何发布事件,通过事件多播器方法:multicastEvent(),进入方法。

@Override
public void multicastEvent(ApplicationEvent event) {multicastEvent(event, resolveDefaultEventType(event));
}
@Overridepublic void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));//从事件多播器中获取出所有的监听器for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {//判断多播器中是否支持异步多播的Executor executor = getTaskExecutor();if (executor != null) {//异步播发事件executor.execute(() -> invokeListener(listener, event));}else {//同步播发invokeListener(listener, event);}}}
/*** Invoke the given listener with the given event.* @param listener the ApplicationListener to invoke* @param event the current event to propagate* @since 4.1*/protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {ErrorHandler errorHandler = getErrorHandler();if (errorHandler != null) {try {doInvokeListener(listener, event);}catch (Throwable err) {errorHandler.handleError(err);}}else {doInvokeListener(listener, event);}}

doInvokeListener() 方法,Spring有一个特点,涉及到以 do 开头的方法都是真正干活的。

 @SuppressWarnings({"rawtypes", "unchecked"})private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {try {listener.onApplicationEvent(event);}catch (ClassCastException ex) {String msg = ex.getMessage();if (msg == null || matchesClassCastMessage(msg, event.getClass())) {// Possibly a lambda-defined listener which we could not resolve the generic event type for// -> let's suppress the exception and just log a debug message.Log logger = LogFactory.getLog(getClass());if (logger.isTraceEnabled()) {logger.trace("Non-matching event type for listener: " + listener, ex);}}else {throw ex;}}}

3.11 finishBeanFactoryInitialization()

实例化所有的非懒加载的单实例 bean,我们前几篇源码,其实都是讲的里面的方法,最重要的就是 getBean()。

3.12 finishRefresh()

最后刷新容器发布刷新事件(Spring cloud eureka 也是从这里启动的)。

protected void finishRefresh() {//初始化生命周期处理器initLifecycleProcessor();//调用生命周期处理器的onRefresh方法getLifecycleProcessor().onRefresh();//发布ContextRefreshedEvent事件publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);}

(1) 初始化生命周期处理器:initLifecycleProcessor() 方法。

protected void initLifecycleProcessor() {//获取beanFactory工厂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 + "]");}}//没有创建一个DefaultLifecycleProcessor,然后注册到容器中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 + "]");}}}

(2) 调用生命周期处理器的 getLifecycleProcessor().onRefresh() 方法。

@Override
public void onRefresh() {startBeans(true);this.running = true;
}

startBeans(true) 方法,主要的功能是找到 Spring 容器的 Lifecycle 类型的 Bean,然后调用 start() 去启动。

private void startBeans(boolean autoStartupOnly) {Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {Lifecycle bean = entry.getValue();if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {int phase = getPhase(bean);LifecycleGroup group = phases.get(phase);if (group == null) {group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);phases.put(phase, group);}group.add(entry.getKey(), bean);}}if (!phases.isEmpty()) {List<Integer> keys = new ArrayList<Integer>(phases.keySet());Collections.sort(keys);for (Integer key : keys) {phases.get(key).start();}}}

phases.get(key).start() 方法。

  public void start() {if (this.members.isEmpty()) {return;}if (logger.isDebugEnabled()) {logger.debug("Starting beans in phase " + this.phase);}Collections.sort(this.members);for (LifecycleGroupMember member : this.members) {doStart(this.lifecycleBeans, member.name, this.autoStartupOnly);}}
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {Lifecycle bean = lifecycleBeans.remove(beanName);if (bean != null && bean != this) {String[] dependenciesForBean = getBeanFactory().getDependenciesForBean(beanName);for (String dependency : dependenciesForBean) {doStart(lifecycleBeans, dependency, autoStartupOnly);}//bean不在运行中并且(autoStartupOnly=false 或者 不是SmartLifecycle类型 或者 isAutoStartup() = true)if (!bean.isRunning() &&(!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {if (logger.isDebugEnabled()) {logger.debug("Starting bean '" + beanName + "' of type [" + bean.getClass().getName() + "]");}try {//调用生命周期Lifecycle Bean的start()方法bean.start();}catch (Throwable ex) {throw new ApplicationContextException("Failed to start bean '" + beanName + "'", ex);}if (logger.isDebugEnabled()) {logger.debug("Successfully started bean '" + beanName + "'");}}}}

(3) 发布 ContextRefreshedEvent 事件:主要就是调用前面第八步创建的事件多播器的发布事件方法。

protected void publishEvent(Object event, ResolvableType eventType) {Assert.notNull(event, "Event must not be null");if (logger.isTraceEnabled()) {logger.trace("Publishing event in " + getDisplayName() + ": " + event);}// Decorate event as an ApplicationEvent if necessaryApplicationEvent applicationEvent;if (event instanceof ApplicationEvent) {applicationEvent = (ApplicationEvent) event;}else {applicationEvent = new PayloadApplicationEvent<Object>(this, event);if (eventType == null) {eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();}}// Multicast right now if possible - or lazily once the multicaster is initializedif (this.earlyApplicationEvents != null) {this.earlyApplicationEvents.add(applicationEvent);}else {getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);}// Publish event via parent context as well...if (this.parent != null) {if (this.parent instanceof AbstractApplicationContext) {((AbstractApplicationContext) this.parent).publishEvent(event, eventType);}else {this.parent.publishEvent(event);}}}

4. 总结

总结一下本文内容:

  • 讲述了 IOC 的基础知识,并通过婚介所的示例,讲解容器的创建过程;

  • 介绍容器创建的 4 个相关对象,以及 refresh() 的主流程;

  • 给出 refresh() 的 12 个主流程的核心源码,并附上详细注释。

大家主要掌握 IOC 容器创建的思想和过程,以及 refresh() 的 12 个主流程即可,至于里面每一步流程,如果深究下去,其实内容非常多,建议后续如果需要,再深入学习。

Spring IOC和Bean生命周期以及源码分析相关推荐

  1. php 变量存活期,php 变量生命周期:PHP源码分析-PHP的生_php

    php的最多的两种运行模式是web模式.CLI模式. 无论哪种模式,PHP工作原理都是一样的,作为一种SAPI运行. 1.当我们在终端敲入php这个命令的时候,它使用的是CLI. 它就像一个web服务 ...

  2. Spring5源码 - 07 Spring Bean 生命周期流程 源码解读02

    文章目录 Pre 通俗流程 finishBeanFactoryInitialization Pre Spring5源码 - 06 Spring Bean 生命周期流程 概述 01 接上文 通俗流程 下 ...

  3. Spring IOC容器和获取组件对象源码分析

    打上断点进行调试 1 第一步是进入了ClassPathXmlApplicationContext调用其构造参数,其中配置文件的内容被解析成了数组 public ClassPathXmlApplicat ...

  4. 【Spring学习】Bean生命周期

    我理解的Bean生命周期包括两个方面: Bean何时创建,何时销毁 Bean从创建到销毁的执行流程 一.Bean创建与销毁 Bean的创建时机主要由几个配置项共同来决定,包括: scope属性,决定是 ...

  5. 【Spring系列】- Bean生命周期底层原理

    Bean生命周期底层原理

  6. Spring自定义注解驱动开发使用及源码分析

    目录 前言 注解驱动开发使用 需求 代码实现 测试效果 源码分析 BeanDefinitionRegistryPostProcessor接口 解析BeanDefinition 处理Bean上配置的注解 ...

  7. 聊聊Spring中的数据绑定 --- DataBinder本尊(源码分析)

    每篇一句 唯有热爱和坚持,才能让你在程序人生中屹立不倒,切忌跟风什么语言或就学什么去~ 相关阅读 [小家Spring]聊聊Spring中的数据转换:Converter.ConversionServic ...

  8. 聊聊Spring中的数据绑定 --- DataBinder本尊(源码分析)【享学Spring】

    每篇一句 唯有热爱和坚持,才能让你在程序人生中屹立不倒,切忌跟风什么语言或就学什么去~ 前言 数据绑定 这个概念在任何一个成型的框架中都是特别重要的(尤其是web框架),它能让框架更多的自动化,更好容 ...

  9. 【小家Spring】聊聊Spring中的数据绑定 --- DataBinder本尊(源码分析)

    每篇一句 > 唯有热爱和坚持,才能让你在程序人生中屹立不倒,切忌跟风什么语言或就学什么去~ 相关阅读 [小家Spring]聊聊Spring中的数据绑定 --- 属性访问器PropertyAcce ...

最新文章

  1. python打开是什么颜色-python图片颜色
  2. mybatis学习7之动态sql
  3. u盘往linux考文件过大,U盘拷贝时提示文件过大怎么办,教您如何解决
  4. 项目管理在企业发展中的作用及未来的发展方向—— 来自项目管理群的讨论
  5. arm cortex-a8 天梯图_ARM正式推出CortexA78C核心:针对笔记本电脑设计、支持8个大核心...
  6. C语言 define 防止头文件重复包含 - C语言零基础入门教程
  7. 基于Gulp的简易前端自动化工程搭建
  8. 男生看女生叫审美,女生看男生叫好色之新解
  9. 使用 classList API
  10. 【开发心得】json解析报错Uncaught SyntaxError: Unexpected identifier的解决方法
  11. C++获取汉字拼音/简拼/首字母
  12. 【ElasticSearch】ES分页查询超过10000限制解决
  13. 【史上最全】国内外常用精品API接口汇总
  14. 在腾讯云主机上搭建pytorch深度学习环境
  15. 中国石油大学(北京)-《 油层物理》第二阶段在线作业
  16. linux计划任务如何关闭程序,Linux进程控制和计划任务管理
  17. paddlepaddle常见问题解答
  18. 如何在ftp服务器编辑文件,ftp服务器怎么编辑文件
  19. 4.2.3 编程题《将一笔钱换算成1分、2分和5分的硬币组合》
  20. 魔术之间:自变量与因变量的交互

热门文章

  1. RabbitMQ 报错:connection error; (reply-code=530, reply-text=NOT_ALLOWED - XXX(Hosts名) / not found)
  2. Node.js项目中动态加载环境变量配置
  3. 乐乐音乐H5网页版-支持krc歌词(动感歌词、翻译和音译歌词)
  4. 蓝桥杯 砝码称重【第十二届】【动态规划】以及一些总结
  5. 读书:SQL必知必会
  6. C基础第39课--程序中的三国天下--栈,堆,静态存储区
  7. k8s双节点集群搭建详细教程
  8. DTX编解码原理New
  9. Unity3D——添加剑痕效果(PocketRPG Trail插件)
  10. c++ 数组置0_鸣小亮C语言笔记(5)——数组