Spring之IOC
容器:存储单例Bean的实例
基础容器:BeanFactory
高级容器:ApplicationContext
基础容器与高级容器的区别:
基础容器产生Bean实例的时机是第一次被调用的时候。高级容器是服务启动的时候,就会创建所有单例的Bean实例。
BeanFactory和FactoryBean的区别:
BeanFactory是Spring的顶级接口,是Spring中容器的底层实现接口。BeanFactory 实现类管理者所有的单例bean实例。
FactoryBean是spring容器中管理的一个特殊的bean。因为该bean还能产生指定类型的bean实例。
BeanFactoryPostProcessor和BeanPostProcessor的区别:
BeanFactoryPostProcessor主要是在bean【实例创建】之前,beanDefiniton初始化前后去调用。
BeanPostProcessor主要是Bean【实例初始化】前后,对Bean实例进行一些后置操作。
(一)BeanFactory继承体系:
四级接口继承体系:
-
BeanFactory 作为一个主接口不继承任何借口,暂且称之为一级接口。
-
AutowireCapableBeanFactory、HirerarchicalBeanFactory、ListableBeanFactory3个子接口继承了BeanFactory,进行功能上的增强。这三个接口成为二级接口。
-
ConfigurableBeanFactory可以被称为三级接口,对二级接口HirerarchicalBeanFactory进行了再次增强,此外他还继承了另一个外来的接口SingletonBeanRegistry
-
ConfigurableListableBeanFactory是一个更强大得接口,继承了上述得所有接口,无所不包,成为四级接口。
继承关系中的两个抽象类和两个实现类:
-
AbstractBeanFactory作为一个抽象类,实现了三级接口ConfigurableBeanFactory大部分功能。
-
AbstractAutowireCapableBeanFactory同样也是抽象类,继承自AbstractBeanFactory,并额外实现了二级接口AutowireCapableBeanFactory。
-
DefaultListableBeanFactory 继承自 AbstractAutowireCapableBeanFactory ,实现了最强大的四级接口 ConfigurableListableBeanFactory ,并实现了一个外来接口BeanDefinitionRegistry ,它并非抽象类。
-
最后是最强大的xmlBeanFactory,继承自DefaultListableBeanFactory,重写了一些功能,使自己更加强大。
那为何要定义这么多层次的接口呢?
查阅这些接口的源码和说明发现,每个接口都有他使用的场合,它主要是为了区分在Spring内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。例如ListableBeanFactory接口表
示这些Bean是可列表的,而HierarchicalBeanFactory表示的是这些Bean是有继承关系的,也就是每个Bean有可能有父Bean。AutowireCapableBeanFactory接口定义Bean的自动装配规则。这四个接口
共同定义了Bean的集合、Bean之间的关系、以及Bean行为.
1.1 BeanFactory:
public interface BeanFactory { //用来引用一个实例,或把它和工厂产生的Bean区分 就是说,如果一个FactoryBean的名字为a,那么,&a会得到那个Factory String FACTORY_BEAN_PREFIX = "&"; /* * 四个不同形式的getBean方法,获取实例 */ Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; // 是否存在 boolean containsBean(String name); // 是否为单实例 boolean isSingleton(String name) throws NoSuchBeanDefinitionException; // 是否为原型(多实例) boolean isPrototype(String name) throws NoSuchBeanDefinitionException; // 名称、类型是否匹配 boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException; // 获取类型 Class<?> getType(String name) throws NoSuchBeanDefinitionException; // 根据实例的名字获取实例的别名 String[] getAliases(String name); }
在BeanFactory中只对IOC容器的基本行为做了定义,根本不关心bean是如何定义怎样加载的。
1.2.1 ListableBeanFactory
public interface ListableBeanFactory extends BeanFactory { // 对于给定的名字是否含有 boolean containsBeanDefinition(String beanName); // 返回工厂的BeanDefinition总数 int getBeanDefinitionCount(); // 返回工厂中所有Bean的名字 String[] getBeanDefinitionNames(); // 返回对于指定类型Bean(包括子类)的所有名字 String[] getBeanNamesForType(Class<?> type); /* * 返回指定类型的名字 * includeNonSingletons为false表示只取单例Bean,true则不是 * allowEagerInit为true表示立刻加载,false表示延迟加载。 * 注意:FactoryBeans都是立刻加载的。 */ String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit); // 根据类型(包括子类)返回指定Bean名和Bean的Map <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException; <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException; // 根据注解类型,查找所有有这个注解的Bean名和Bean的Map Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException; // 根据指定Bean名和注解类型查找指定的Bean <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType); }
源码说明:
3 个跟BeanDefinition有关的总体操作:BeanDefinition的总数、名字的集合、指定类型的名字的集合。
2个getBeanNamesForType重载方法。根据指定类型(包括子类)获取其对应的所有bean名字。
2个getBeansOfType重载方法。根据类型(包括子类)返回指定Bean名和Bean的Map。
2个跟注解查找有关的方法。根据注解类型,查找Bean名和Bean的Map,以及根据指定Bean名和注解类型查找指定的Bean。
该工厂接口最大的特点是可以列出 工厂可以生产的所有实例。当然工厂并没有直接提供返回所有实例的方法,也没有这个必要。它可以返回指定类型的所有的实例。而且可以通过getBeanDefinitionNames得到工厂所有Bean的名字,然后根据这些名字得到所有的Bean. 这个工厂接口扩展类 BeanFactory的功能,作为上下文指出的二级接口,有9个独有的方法,扩展了跟BeanDefinition的功能,提供了BeanDefinition、BeanName、注解有关的各种操作。它可以根据条件返回Bean的信息集合。
1.2.2 HierarchicalBeanFactory
该接口是一个二级接口们主要实现了工厂的分层。
public interface HierarchicalBeanFactory extends BeanFactory { // 返回本Bean工厂的父工厂 BeanFactory getParentBeanFactory(); // 本地工厂是否包含这个Bean boolean containsLocalBean(String name); }
1.2.3 AutowireCapableBeanFactory
源码说明:
有5个静态不可变变量来指明装配策略。其中一个被spring3.0废弃,一个表示没有自动装配。其余三个分别表示根据名称、类型、构造方法进行装配。
8个跟自动装配有关的方法。2个执行BeanPostProcessors的方法。2个分解指定依赖的方法。
总结:该工厂接口继承自BeanFactory,它扩展了自动装配的功能,根据类定义BeanDefinition装配Bean、执行前、后处理器。
public interface AutowireCapableBeanFactory extends BeanFactory { // 这个常量表明工厂没有自动装配的Bean int AUTOWIRE_NO = 0; // 表明根据名称自动装配 int AUTOWIRE_BY_NAME = 1; // 表明根据类型自动装配 int AUTOWIRE_BY_TYPE = 2; // 表明根据构造方法快速装配 int AUTOWIRE_CONSTRUCTOR = 3; //表明通过Bean的class的内部来自动装配(有没翻译错...)Spring3.0被弃用。 @Deprecated int AUTOWIRE_AUTODETECT = 4; // 根据指定Class创建一个全新的Bean实例 <T> T createBean(Class<T> beanClass) throws BeansException; // 给定对象,根据注释、后处理器等,进行自动装配 void autowireBean(Object existingBean) throws BeansException; // 根据Bean名的BeanDefinition装配这个未加工的Object,执行回调和各种后处理器。 Object configureBean(Object existingBean, String beanName) throws BeansException; // 分解Bean在工厂中定义的这个指定的依赖descriptor Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException; // 根据给定的类型和指定的装配策略,创建一个新的Bean实例 Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; // 与上面类似,不过稍有不同。 Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; // 根据名称或类型自动装配 void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException; //也是自动装配 void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException; //初始化一个Bean... Object initializeBean(Object existingBean, String beanName) throws BeansException; //初始化之前执行BeanPostProcessors Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException; //初始化之后执行BeanPostProcessors Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException; // 分解指定的依赖 Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException; }
1.3 ConfigurableBeanFactory
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory,SingletonBeanRegistry { String SCOPE_SINGLETON = "singleton"; // 单例 String SCOPE_PROTOTYPE = "prototype"; // 原型 //搭配HierarchicalBeanFactory接口的getParentBeanFactory方法 void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException; //设置、返回工厂的类加载器 void setBeanClassLoader(ClassLoader beanClassLoader); ClassLoader getBeanClassLoader(); //设置、返回一个临时的类加载器 void setTempClassLoader(ClassLoader tempClassLoader); ClassLoader getTempClassLoader(); //设置、是否缓存元数据,如果false,那么每次请求实例,都会从类加载器重新加载(热加载) void setCacheBeanMetadata(boolean cacheBeanMetadata); boolean isCacheBeanMetadata();//是否缓存元数据 //Bean表达式分解器 void setBeanExpressionResolver(BeanExpressionResolver resolver); BeanExpressionResolver getBeanExpressionResolver(); //设置、返回一个转换服务 void setConversionService(ConversionService conversionService); ConversionService getConversionService(); //设置属性编辑登记员... void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar); //注册常用属性编辑器 void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass); //用工厂中注册的通用的编辑器初始化指定的属性编辑注册器 void copyRegisteredEditorsTo(PropertyEditorRegistry registry); //设置、得到一个类型转换器 void setTypeConverter(TypeConverter typeConverter); TypeConverter getTypeConverter(); //增加一个嵌入式的StringValueResolver void addEmbeddedValueResolver(StringValueResolver valueResolver); String resolveEmbeddedValue(String value);//分解指定的嵌入式的值 void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);//设置一个Bean后处理器 int getBeanPostProcessorCount();//返回Bean后处理器的数量 void registerScope(String scopeName, Scope scope);//注册范围 String[] getRegisteredScopeNames();//返回注册的范围名 Scope getRegisteredScope(String scopeName);//返回指定的范围 AccessControlContext getAccessControlContext();//返回本工厂的一个安全访问上下文 void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);//从其他的工厂复制相关的所有配置 oid registerAlias(String beanName, String alias) throws BeanDefinitionStoreException; void resolveAliases(StringValueResolver valueResolver);//根据指定的StringValueResolver移除所有的别名 //返回指定Bean合并后的Bean定义 BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;//判断指定Bean是否为一个工厂Bean void setCurrentlyInCreation(String beanName, boolean inCreation);//设置一个Bean是否正在创建 boolean isCurrentlyInCreation(String beanName);//返回指定Bean是否已经成功创建 void registerDependentBean(String beanName, String dependentBeanName);//注册一个依赖于指定bean的Bean String[] getDependentBeans(String beanName);//返回依赖于指定Bean的所欲Bean名 String[] getDependenciesForBean(String beanName);//返回指定Bean依赖的所有Bean名 void destroyBean(String beanName, Object beanInstance);//销毁指定的Bean void destroyScopedBean(String beanName);//销毁指定的范围Bean void destroySingletons(); //销毁所有的单例类 }
1.4 ConfigurableListableBeanFactory
1 | BeanFactory的集大成者 |
public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory { void ignoreDependencyType(Class<?> type);//忽略自动装配的依赖类型 void ignoreDependencyInterface(Class<?> ifc);//忽略自动装配的接口 //注册一个可分解的依赖 void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue); //判断指定的Bean是否有资格作为自动装配的候选者 boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException; // 返回注册的Bean定义 BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; // 暂时冻结所有的Bean配置 void freezeConfiguration(); // 判断本工厂配置是否被冻结 boolean isConfigurationFrozen(); // 使所有的非延迟加载的单例类都实例化。 void preInstantiateSingletons() throws BeansException; }
总结:
BeanFactory 的定义由 AbstractBeanFactory 抽象类实现接口的 getBean 方法. 而 AbstractBeanFactory 又继承了实现了 SingletonBeanRegistry 的DefaultSingletonBeanRegistry 类。这样 AbstractBeanFactory 抽象类就具备了单例Bean的注册功能。
AbstractBeanFactory中又定义了两个抽象方法:
1 getBeanDefinition(String beanName)【因为每当需要bean定义元数据时,AbstractBeanFactory这个类都会调用这个方法,根据具体bean工厂实现的性质,此操作可能会很昂贵
(例如,由于外部注册表中的目录查找)。然而,对于可列表bean工厂,这通常只相当于本地哈希查找】、该抽象方法由DefaultListableBeanFactory实现。
2 createBean(String beanName, BeanDefinition beanDefinition) ,这个抽象方法由AbstractAutowireCapableBeanFactory 实现。
最终DefaultListableBeanFactory还会继承抽象类AbstractAutowireCapableBeanFactory 也就可以调用抽象类中的createBean 方法了。
2 BeanDefinitionRegistry
public interface BeanDefinitionRegistry extends AliasRegistry { // 给定bean名称,注册一个新的bean定义 void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException; //根据指定Bean名移除对应的Bean定义 void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; //根据指定bean名得到对应的Bean定义 BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; //查找,指定的Bean名是否包含Bean定义 boolean containsBeanDefinition(String beanName); String[] getBeanDefinitionNames();//返回本容器内所有注册的Bean定义名称 int getBeanDefinitionCount();//返回本容器内注册的Bean定义数目 boolean isBeanNameInUse(String beanName);//指定Bean名是否被注册过。 }
BeanDefinition继承体系:
SpringIOC容器管理了我们定义的各种Bean对象及其相互的关系,Bean对象在Spring实现中是以BeanDefinition来描述的,其继承体系如下:
(二)ApplicationContext继承体系:

下面介绍一下ApplicationContext初始化容器的过程:
测试代码:
@Test public void testApplicationContext(){ ApplicationContext context = new ClassPathXmlApplicationContext(".\\HelloSpring\\src\\Beans.xml"); HelloWorld obj = context.getBean("helloWorld",HelloWorld.class); obj.getMessage(); }
调用refresh方法:
org.springframework.context.support public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext { public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); this.setConfigLocations(configLocations); if (refresh) { //开始调用模板方法 this.refresh(); } } }
上层抽象类的AbstractApplicationContext的refresh方法.
// 完成IoC容器的创建及初始化工作 @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // STEP 1: 刷新预处理 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // STEP 2: // a) 创建IoC容器(DefaultListableBeanFactory) // b) 加载解析XML文件(最终存储到Document对象中) // c) 读取Document对象,并完成BeanDefinition的加载和注册工作 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // STEP 3: 对IoC容器进行一些预处理(设置一些公共属性) prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // STEP 4: postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // STEP 5: 调用BeanFactoryPostProcessor后置处理器对BeanDefinition处理 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation.
//注册BeanPostProcessor后置处理器
// STEP 6:找到BeanPostProcessor的实现,排序后注册到容器 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // STEP 7: 初始化一些消息源(比如处理国际化的i18n等消息源) initMessageSource(); // Initialize event multicaster for this context. // STEP 8: 初始化应用事件广播器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // STEP 9: 初始化一些特殊的bean onRefresh(); // Check for listener beans and register them. // STEP 10: 注册一些监听器 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // STEP 11: 实例化剩余的单例bean(非懒加载方式) // 注意事项:Bean的IoC、DI和AOP都是发生在此步骤 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // STEP 12: 完成刷新时,需要发布对应的事件
//初始化生命周期处理器,调用生命周期处理器的onfresh方法,发布ContextRefreshedEvent事件 JMX相关处理
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(); } }
几个关键类的介绍:
AbstractBeanDefinitionReader:实现BeanDefinitionReader接口的 bean 定义读取器的抽象基类。提供通用属性,例如要处理的 bean 工厂和用于加载 bean 类的类加载器。
XmlBeanDefinitionReader: XML bean 定义的 bean 定义阅读器。将实际的 XML 文档读取委托给BeanDefinitionDocumentReader接口的实现。通常应用于DefaultListableBeanFactory或GenericApplicationContext 。此类加载一个 DOM 文档并将 BeanDefinitionDocumentReader 应用到它。文档阅读器将向给定的 bean 工厂注册每个 bean 定义,并与后者的BeanDefinitionRegistry接口实现对话。
DefaultBeanDefinitionDocumentReader:BeanDefinitionDocumentReader接口的默认实现,该接口根据“spring-beans”DTD 和 XSD 格式(Spring 的默认 XML bean 定义格式)读取 bean 定义。所需 XML 文档的结构、元素和属性名称在此类中进行了硬编码。 (当然,如果需要生成这种格式,可以运行转换)。 <beans>不需要是 XML 文档的根元素:该类将解析 XML 文件中的所有 bean 定义元素,而不考虑实际的根元素。
BeanDefinitonParserDelegate:用于解析 XML bean 定义的有状态委托类。供主解析器和任何扩展BeanDefinitionParsers或BeanDefinitionDecorators使用。该类可以通过解析<bean>标签,获取BeanDefinition对象。
注册Bean的调用链,中间调用过程需要结合ApllicationContext继承体系看。然后结合代码本地debug一下,对于途中的函数,可以重点看下细节。
特别解释: 进入AbstractXmlApplicationContext类后就到了一个到转折点, 由XmlBeanDefinitionReader开始进行读取文件信息和注册BeanDefinition. 随后的过程就和xmLBeanFactory注册BeanDefinition的过程基本相同了.
两个扩展接口的说明:
满足于对 Bean 对象扩展的两个接口,其实也是 Spring 框架中非常具有重量级的两个接口:BeanFactoryPostProcessor 和 BeanPostProcessor,也几乎是大家在使用 Spring 框架额外新增开发自己组建需求的两个必备接口。
BeanFactoryPostProcessor,是由Spring框架组建提供的容器扩展机制,允许在Bean对象注册后但未实例化之前,对Bean的定义信息BeanDefinition执行修改操作。
BeanPostProcessor,也是Spring提供的扩展机制,不过BeanPostProcessor是在Bean对象实例化之后修改Bean对象,也可以替换Bean对象。这部分与后面要实现的 AOP 有着密切的关系。
初始化与销毁的说明:
在 spring.xml 配置中添加 init-method、destroy-method 两个注解,在配置文件加载的过程中,把注解配置一并定义到 BeanDefinition 的属性当中。这样在 initializeBean 初始化操作的工程中,就可以通过反射的方式来
调用配置在Bean定义属性当中的方法信息了。另外如果是接口实现的方式,那么直接可以通过Bean对象调用对应接口定义的方法即可,((InitializingBean) bean).afterPropertiesSet(),两种方式达到的效果是一样的。
除了在初始化做的操作外,destroy-method和DisposableBean接口的定义,都会在Bean对象初始化完成阶段,执行注册销毁方法的信息到DefaultSingletonBeanRegistry类中的disposableBeans属性里,
这是为了后续统一进行操作。这里还有一段适配器的使用,因为反射调用和接口直接调用,是两种方式。所以需要使用适配器进行包装,下文代码讲解中参考 DisposableBeanAdapter的具体实现 -关于销毁方法需要在虚拟机执行关闭之前
进行操作,所以这里需要用到一个注册钩子的操作,如:Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("close!"))); 这段代码你可以执行测试,
另外你可以使用手动调用 ApplicationContext.close 方法关闭容器。
ApllicationContext的bean初始化流程:

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)