相信很多同学在学习Spring源码时,总会被Spring IoC和应用上下文复杂的层次性所搞晕,debug时一会调到这个类某个方法一会调到那个类的某个方法,经常搞得晕头转向的,今天我们就分析下Spring IoC和应用上下文(ApplicationContext)的层次,每个接口定义了哪些方法,它们的作用是什么?

BeanFactory

这里我们以Spring 中唯一可用的IoC产品-DefaulListableBeanFactory的类关系图为例。

AliasRegistry

简单来说,该接口定义了和别名注册相关的新增、移除、查询等方法。

public interface AliasRegistry {/*** 注册指定name的别名(alias)*/void registerAlias(String name, String alias);/*** 移除别名*/void removeAlias(String alias);/*** 判断给定的name是否是别名*/boolean isAlias(String name);/*** 根据name获取其关联的所有别名*/String[] getAliases(String name);}

SingletonBeanRegistry

该接口定义了一系列和单例Bean相关的注册、查询、判断相关方法。

public interface SingletonBeanRegistry {/*** 注册单例Bean*/void registerSingleton(String beanName, Object singletonObject);/*** 根据给定的beanName获取单例Bean*/@NullableObject getSingleton(String beanName);/*** 根据给定的beanName判断是否包含其实例*/boolean containsSingleton(String beanName);/*** 获取已注册的所有单例Bean名称*/String[] getSingletonNames();/*** 获取已注册的单例Bean数量*/int getSingletonCount();/*** 获取互斥条件*/Object getSingletonMutex();}

BeanDefinitionRegistry

该接口定义了一系列和Bean元数据(BeanDefinition)相关的新增、移除、查询方法。

public interface BeanDefinitionRegistry extends AliasRegistry {/*** 注册BeanDefinition*/void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;/*** 根据给定的beanName移除其BeanDefinition*/void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;/*** 根据给定的beanName获取其BeanDefinition*/BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;/*** 根据给定的beanName判断是否包含其BeanDefinition*/boolean containsBeanDefinition(String beanName);/*** 获取已注册的所有BeanDefinition名称*/String[] getBeanDefinitionNames();/*** 获取已注册的BeanDefinition数量*/int getBeanDefinitionCount();/*** 判断指定beanName是否被使用*/boolean isBeanNameInUse(String beanName);}

BeanFactory

简而言之,该接口就是一个单一类型的Bean查找接口,所有实现了该接口的IoC容器都具备根据类型或名字来查找单个Bean的能力。

public interface BeanFactory {/*** 根据beanName来查找Bean*/Object getBean(String name) throws BeansException;/*** 根据beanName和类型来查找Bean*/<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;/*** 根据beanName和构造函数参数/工厂方法参数来查找Bean*/Object getBean(String name, Object... args) throws BeansException;/*** 根据类型来查找Bean*/<T> T getBean(Class<T> requiredType) throws BeansException;/*** 根据类型和构造函数参数/工厂方法来查找Bean*/<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;/*** 根据指定类型来延迟查找Bean*/<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);/*** 根据给定的ResolvableType 来延迟查找Bean。*/<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);/*** 是否包含指定Bean*/boolean containsBean(String name);/*** 根据名字判断指定Bean是否是单例*/boolean isSingleton(String name) throws NoSuchBeanDefinitionException;/*** 根据名字判断指定Bean是否是原型*/boolean isPrototype(String name) throws NoSuchBeanDefinitionException;/*** 检查给定的beanName是否与指定的类型匹配。*/boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;/*** 检查给定的beanName是否与指定的类型匹配。*/boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;/*** 根据名字来获取其类型*/@NullableClass<?> getType(String name) throws NoSuchBeanDefinitionException;/*** 根据名字来获取其相关的别名*/String[] getAliases(String name);}

ListableBeanFactory

简而言之,该接口就是一个集合类型Bean查找接口,让所有继承或实现该接口的类具有列表查找Bean的能力。

public interface ListableBeanFactory extends BeanFactory {/*** 根据beanName判断是否包含指定BeanDefinition*/boolean containsBeanDefinition(String beanName);/*** 获取BeanFactory中所有BeanDefinition数量*/int getBeanDefinitionCount();/*** 获取BeanFactory中所有BeanDefinition的名字*/String[] getBeanDefinitionNames();/*** 获取所有该类型的beanName*/String[] getBeanNamesForType(ResolvableType type);/*** 获取该类型的所有beanName*/String[] getBeanNamesForType(@Nullable Class<?> type);/*** 获取该类型的所有beanName,可以通过allowEagerInit参数来控制FactoryBean是否提前实例化,通过includeNonSingletons来控制是否忽略非单例*/String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);/*** 获取该类型的所有beanName以及相应实例*/<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;/*** 获取该类型的所有beanName以及相应实例,可以通过allowEagerInit参数来控制FactoryBean是否提前实例化,通过includeNonSingletons来控制是否忽略非单例*/<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)throws BeansException;/*** 获取所有添加了指定注解类型的beanName*/String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);/*** 获取所有添加了指定注解类型的beanName(key)以及Bean实例(value)*/Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;/*** 查找指定类型上的指定注解数据*/@Nullable<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)throws NoSuchBeanDefinitionException;}

HierarchicalBeanFactory

该接口允许IoC容器设置父容器(getParentBeanFactory),使得IoC容器拥有了父子容器关系。以及只判断当前IoC容器是否包含指定Bean(containsLocalBean)方法。

public interface HierarchicalBeanFactory extends BeanFactory {/*** 返回父bean工厂,如果没有,则返回null*/@NullableBeanFactory getParentBeanFactory();/*** 返回当前bean工厂中是否包含给定名称的bean,忽略在父上下文中定义的bean*/boolean containsLocalBean(String name);}

ConfigurableBeanFactory

该接口定义了设置BeanFactory相关行为的方法,如果需要对BeanFactory进行配置,可以查看该接口中定义的方法。

public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {/*** 允许BeanFactory设置父容器*/void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;/*** 设置BeanClassLoader*/void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);/*** 获取BeanClassLoader*/@NullableClassLoader getBeanClassLoader();/*** 设置临时ClassLoader*/void setTempClassLoader(@Nullable ClassLoader tempClassLoader);/*** 获取临时ClassLoader*/@NullableClassLoader getTempClassLoader();/*** 设置是否缓存Bean元数据*/void setCacheBeanMetadata(boolean cacheBeanMetadata);/*** 获取是否缓存Bean元数据设置*/boolean isCacheBeanMetadata();/*** 设置Bean表达式解析器*/void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);/*** 获取Bean表达式解析器*/@NullableBeanExpressionResolver getBeanExpressionResolver();/*** 设置统一类型转换服务*/void setConversionService(@Nullable ConversionService conversionService);/*** 获取统一类型转换服务*/@NullableConversionService getConversionService();/*** 添加属性编辑器注册器*/void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);/*** 注册自定义的属性编辑器*/void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);/*** 复制已注册的属性编辑器至目标属性编辑器注册表*/void copyRegisteredEditorsTo(PropertyEditorRegistry registry);/*** 设置类型转换器*/void setTypeConverter(TypeConverter typeConverter);/*** 获取类型转换器*/TypeConverter getTypeConverter();/*** 添加嵌入式解析器(解析@value注解)*/void addEmbeddedValueResolver(StringValueResolver valueResolver);/*** 判断是否存在嵌入式解析器*/boolean hasEmbeddedValueResolver();/*** 移除嵌入式解析器*/@NullableString resolveEmbeddedValue(String value);/*** 添加BeanPostProcessor*/void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);/*** 获取已注册的BeanPostProcessor数量*/int getBeanPostProcessorCount();/*** 注册自定义Bean作用域*/void registerScope(String scopeName, Scope scope);/*** 获取已注册的Bean作用域名字*/String[] getRegisteredScopeNames();/*** 根据作用域名字来获取指定作用域*/@NullableScope getRegisteredScope(String scopeName);/*** 获取访问控制上下文*/AccessControlContext getAccessControlContext();/*** 复制当前BeanFactory配置至目标BeanFactory*/void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);/*** 注册别名*/void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;/*** 解析别名*/void resolveAliases(StringValueResolver valueResolver);/*** 根据beanName获取合并后的BeanDefinition*/BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;/*** 根据beanName判断是否是FactoryBean*/boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;/*** 将给定的beanName设置其是否正在创建*/void setCurrentlyInCreation(String beanName, boolean inCreation);/*** 根据beanName判断正在创建*/boolean isCurrentlyInCreation(String beanName);/*** 注册指定beanName所依赖的beanName*/void registerDependentBean(String beanName, String dependentBeanName);/*** 根据beanName获取所有依赖它的beanName*/String[] getDependentBeans(String beanName);/*** 根据beanName获取它依赖的所有beanName*/String[] getDependenciesForBean(String beanName);/*** 销毁Bean*/void destroyBean(String beanName, Object beanInstance);/*** 销毁作用域Bean*/void destroyScopedBean(String beanName);/*** 销毁所有的单例*/void destroySingletons();}

AutowireCapableBeanFactory

该接口定义了一系列和Bean自动装配相关的方法,如果需要对Bean属性的自动装配进行一些操作,可以查看该接口定义的方法。

public interface AutowireCapableBeanFactory extends BeanFactory {/*** 创建指定类型的Bean实例,返回的Bean处于就绪状态*/<T> T createBean(Class<T> beanClass) throws BeansException;/*** 处理给定Bean的依赖项*/void autowireBean(Object existingBean) throws BeansException;/*** 配置Bean的自动装配属性,并调用其工厂方法*/Object configureBean(Object existingBean, String beanName) throws BeansException;/*** 创建指定类型的Bean实例,返回的Bean处于就绪状态,可以通过参数autowireMode来控制其依赖注入模型,例如是根据类型注入还是根据名称注入*/Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;/*** 使用指定的自动装配模型来实例化给定类的bean实例*/Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;/*** 根据名称或类型自动装配给定bean实例的bean属性。*/void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)throws BeansException;/*** 将给定的beanName对应的bean所定义的属性值应用到给定的bean实例*/void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;/*** 执行给定Bean的生命周期方法*/Object initializeBean(Object existingBean, String beanName) throws BeansException;/*** 根据给定的Bean来执行BeanPostProcessor实现类的postProcessorsBeforeInitialization方法*/Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException;/*** 根据给定的Bean来执行BeanPostProcessor实现类的postProcessorsAfterInitialization(方法*/Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException;/*** 销毁Bean,执行Bean中的相关销毁方法*/void destroyBean(Object existingBean);/*** 解析唯一匹配给定对象类型(如果有的话)的bean实例,*/<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;/*** 为给定的bean名称解析一个bean实例,提供一个依赖描述符*/Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;/*** 根据依赖描述符解析其依赖项*/@NullableObject resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;/*** 根据依赖描述符解析其依赖项,可以指定候选的beanName以及相应的类型转换器*/@NullableObject resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;}

ConfigurableListableBeanFactory

ConfigurableListableBeanFactory接口在ConfigurableBeanFactory接口基础之上更进一步,新增了支持添加忽略依赖类型和支持依赖类型的方法,但最重要的是其定义的preInstantiateSingletons方法,通过调用该方法,可以使IoC容器中所有非懒加载的单例Bean进行实例化以及初始化。

public interface ConfigurableListableBeanFactoryextends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {/*** 注册要忽略的依赖类型*/void ignoreDependencyType(Class<?> type);/*** 注册要忽略的依赖接口类型*/void ignoreDependencyInterface(Class<?> ifc);/*** 注册支持的依赖接口类型*/void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);/*** 判断指定的bean是否符合自动装配候选条件*/boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)throws NoSuchBeanDefinitionException;/*** 根据给定的beanName获取其BeanDefinition*/BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;/*** 获取BeanName迭代器*/Iterator<String> getBeanNamesIterator();/*** 清除元数据缓存*/void clearMetadataCache();/*** 冻结配置*/void freezeConfiguration();/*** 获取配置冻结状态*/boolean isConfigurationFrozen();/*** 初始化所有单例Bean*/void preInstantiateSingletons() throws BeansException;}

Spring IoC容器层次总结

以上就是我们对IoC容器层次性分析,其实总结起来也很简单:

AliasRegistry接口定义了一系列和别名相关的增删查方法。
SingletonBeanRegistry接口定义了一系列和单例Bean相关的增删查方法。
BeanFactory接口定义了IoC容器的基本功能,例如单一类型的Bean查找,判断指定Bean是否是单例或者是原型;
ListableBeanFactory接口在BeanFactory基础上扩展了列表类型Bean查找的功能;HierarchicalBeanFactory接口在BeanFactory基础上扩展了允许IoC容器存在层次性;ConfigurableBeanFactory接口在HierarachicalBeanFactory以及SingletonBeanRegistry基础上扩展了可配置IoC容器的功能。
AutowireCapableBeanFactory接口定义了一系列和Bean自动装配相关的方法,其实就是可以处理Bean的依赖项。
ConfigurableListableBeanFactory在ConfigurableBeanFactory基础上更进一步,支持配置IoC容器可以处理以及需要忽略的依赖项(这些要忽略的依赖项有BeanFactoryAware、ApplicationContextAware等)。但最重要的是其定义的preInstantiateSingletons方法,通过该方法可以预实例化所有的单例Bean。

Spring应用上下文

在Spring应用上下文-ApplicationContext层次性分析这块,我们以注解驱动的应用上下文-AnnotationConfigApplicationContext层次分析为例。

ApplicationContext

ApplicationContext是Spring 应用上下文模块的根接口,该接口通过继承EnvironmentCapable、ListableBeanFactory、HierarchicalBeanFactory、MessageSource、ApplicationEventPublisher、ResourcePatternResolver 这六个接口来确定了应用上下文的基本功能。

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {/*** 返回当前上下文ID*/@NullableString getId();/*** 获取当前应用上下文名称*/String getApplicationName();/*** 获取显示的名字*/String getDisplayName();/*** 获取启动时间*/long getStartupDate();/*** 获取父容器*/@NullableApplicationContext getParent();/*** 获取AutowireCapableBeanFactory实例*/AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;}

EnvironmentCapable

EnvironmentCapable 接口十分简单,该接口标识其具有环境能力。

public interface EnvironmentCapable {/*** 返回关联的环境*/Environment getEnvironment();}

MessageSource

MessageSource 接口定义了国际化相关的能力,该接口的存在感很弱并且日常开发基本用不到,这里我们就不详细分析了。

public interface MessageSource {/*** 根据 code以及参数和本地语言环境来获取对应的文案,如果没有那就使用传入的默认文案(defaultMessage)*/@NullableString getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);/*** 根据 code以及参数和本地语言环境来获取对应的文案*/String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;/*** 根据MessageSourceResolvable以及本地语言环境来获取对应的文案*/String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;}

ApplicationEventPublisher

ApplicationEventPublisher 接口定义了发布应用上下文事件的能力。

@FunctionalInterface
public interface ApplicationEventPublisher {/*** 发布应用上下文事件,限定事件类型必须为ApplicationEvent 类型*/default void publishEvent(ApplicationEvent event) {publishEvent((Object) event);}/*** 发布应用上下文事件,事件类型可以是任意类型*/void publishEvent(Object event);}

ResourcePatternResolver

ResourcePatternResolver 接口定义了根据通配路径来加载资源(多个)的能力,其继承的ResourceLoader只定义了根据路径来加载单个资源的能力。

public interface ResourcePatternResolver extends ResourceLoader {/*** 根据给定通配路径来加载资源*/Resource[] getResources(String locationPattern) throws IOException;}

Lifecycle

Lifecycle 接口定义了Spring应用上下文生命周期相关方法。

public interface Lifecycle {/*** 应用上下文启动*/void start();/*** 应用上下文停止*/void stop();/*** 是否正在运行*/boolean isRunning();}

ConfigurableApplicationContext

该接口和ConfigurableBeanFactory接口作用相似,提供配置Spring应用上下文相关方法。

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {/*** 设置应用上下文ID*/void setId(String id);/*** 设置父应用上下文*/void setParent(@Nullable ApplicationContext parent);/*** 设置环境对象*/void setEnvironment(ConfigurableEnvironment environment);/*** 获取关联的环境对象*/@OverrideConfigurableEnvironment getEnvironment();/*** 添加BeanFactoryPostProcessor实现类*/void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);/*** 添加应用程序监听器*/void addApplicationListener(ApplicationListener<?> listener);/*** 添加协议解析器*/void addProtocolResolver(ProtocolResolver resolver);/*** Spring 应用上下文中最重要的方法,刷新Spring应用上下文*/void refresh() throws BeansException, IllegalStateException;/*** 注册应用上下文钩子线程(和JVM关闭时的钩子方法有关)*/void registerShutdownHook();/*** 关闭应用上下文*/@Overridevoid close();/*** 返回当前应用上下文活跃状态*/boolean isActive();/*** 获取当前Spring应用上下文所关联的ConfigurableListableBeanFactory实例*/ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;}

AnnotationConfigRegistry

该接口定义了配置类注册能力以及根据包路径进行类资源扫描能力。

public interface AnnotationConfigRegistry {/*** 注册配置类*/void register(Class<?>... annotatedClasses);/*** 根据指定包路径扫描资源*/void scan(String... basePackages);}

Spring应用上下文层次总结

Spring 应用上下文层次总结起来也很简单,根接口是ApplicationContext。该接口只定义了获取启动时间、应用程序显示名字、应用程序名字、应用程序ID、Spring应用上下文层次以及获取关联的BeanFactory对象。
EnvironmentCapable接口定义了获取Environemnt对象。
MessageSource接口定义了Spring国际化相关方法。
ApplicationEventPublisher接口定义了事件发布相关方法。
ResourcePatternResolver接口定义了通配路径资源解析相关方法。
Lifecycle接口定义了Spring 应用上下文生命周期相关方法。
ConfigurableApplicationContext 接口定义了可配置Spring应用上下文相关方法。
AnnotationConfigRegistry接口定义了注册配置以及扫描指定包路径相关方法。

结束语

以上就是我们对Spring IoC以及应用上下文层次相关分析,这里我们没有具体的类进行分析,因为无论是抽象类还是具体的类都是对接口的方法进行实现,扩展很少。

其实想要理解Spring IoC以及应用上下文层次非常简单,因为Spring 会把一组功能放到一个接口中(这也是接口隔离、单一职责规范的体现),这也是只需要记住每个接口它们的大致职责是什么,这样有需要的时候,就可以去查看具体接口中有哪些方法。

Spring IoC、应用上下文容器层次分析相关推荐

  1. 浅入 spring ioc 单例容器

    我们要干嘛? 1, 分析IOC 是怎么扫描路径 2, 对象是怎么被加载进容器的 3, 对象是怎么从容器里获取 4, 执行方法 案例代码, 网上一大顿分析xml的, 太low了, 我们直接从注解模式, ...

  2. 基于上下文的rpn_构建事物-产品评论视频中基于上下文的情感分析

    基于上下文的rpn The word "Social" has taken a whole new meaning in today's digital era. Simply g ...

  3. Spring IOC 容器源码分析

    Spring IOC 容器源码分析 创建时间: 2017-11-15 00:00:00 [TOC] Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring ...

  4. Spring IOC 容器源码分析 - 填充属性到 bean 原始对象

    1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...

  5. Spring IOC 容器源码分析系列文章导读 1

    1. 简介 Spring 是一个轻量级的企业级应用开发框架,于 2004 年由 Rod Johnson 发布了 1.0 版本.经过十几年的迭代,现在的 Spring 框架已经非常成熟了.Spring ...

  6. Spring IOC 容器源码分析系列文章导读

    1. 简介 前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解.在写完 Spring IOC 容器源码分析系列文章中的最后一篇后,没敢懈怠,趁热打铁,花了3天时间阅 ...

  7. Spring IOC 容器源码分析 - 余下的初始化工作

    1. 简介 本篇文章是"Spring IOC 容器源码分析"系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的 bea ...

  8. Spring IOC 容器源码分析 - 循环依赖的解决办法

    1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...

  9. Spring IOC 容器源码分析 - 创建原始 bean 对象

    1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...

  10. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

最新文章

  1. free not return memory
  2. python中bin是什么意思_Python之一、#!/usr/bin/python到底是什么意思
  3. Python调用模块发送邮件(粗糙版)
  4. 从Windows上用SSH链接接入Ubuntu
  5. 解决ubuntu系统root用户下Chrome无法启动问题
  6. Java工作笔记-@Value注解的使用(可用于配置文件)
  7. Windows 编程[8] - WM_PAINT 消息
  8. 二层、三层、四层交换的比较
  9. 蓝鲸社区版_部署bkdata服务无法启动问题
  10. linux 指定范围内查找文件,Linux Find命令查找指定时间范围内的文件的例子
  11. python flask框架 蓝图的使用
  12. 机器学习之集成学习概述
  13. Merge k Sorted Lists
  14. 这位辩手,你想试试线上语音 battle 么?
  15. python使用gps设备
  16. NLP - 结巴分词 词云
  17. 如何显示计算机窗口的状态栏,如何让电脑任务栏不显示打开的程序或窗口方法...
  18. python怎么算二元一次方程_Python简单实现二元一次方程求根
  19. 2021-2027全球与中国地质与矿山规划软件市场现状及未来发展趋势
  20. java jar 最大内存大小_Java运行Jar包内存配置的操作

热门文章

  1. SLAM--求解2D-2D图像间的运动
  2. assert断言的概念
  3. 1193, Unknown system variable 'tx_isolation'
  4. php 调用dll静态库,vue-cli 2.x 项目优化之引入本地静态库文件
  5. hdu acm 1540
  6. 基于IDEA使用Spark API开放Spark程序(1)
  7. 计算机图形学完整笔记(八):曲线曲面 - 2
  8. 【Gym-101889 D】Daunting device【分块】
  9. 设A和B是n阶矩阵 ,A,B,A+B均可逆,证明:(A^-1+B^-1)也可逆,并求其逆。
  10. 使用re正则匹配网络请求到的正文内容,筛选出jpg图片链接