BeanFactory 是 Spring 的“心脏”。它就是 Spring IoC 容器的真面目。Spring 使用 BeanFactory 来实例化、配置和管理 Bean。
首先我们看一下spring源码中的对于该接口的注释,如下
/**
* The root interface for accessing a Spring bean container.
* 访问 Spring bean 容器的根接口
*
* This is the basic client view of a bean container;
* further interfaces such as {@link ListableBeanFactory} and
* {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
* are available for specific purposes.
*/
解释如下:访问 Spring bean 容器的根接口。访问Spring bean容器的根接口。这是 bean 容器的基本客户端视图
说明这个接口是一个操作bean的最底层的基础接口,定义了IOC容器的最基本形式,并提供了IOC容器应遵守的的最基本的接口,也就是Spring IOC所遵守的最底层和最基本的编程规范。在Spring代码中,BeanFactory只是个接口,并不是IOC容器的具体实现。
BeanFactory的接口定义,API说明
名称 | 方法描述 | 返回值 | code |
---|---|---|---|
getBean | 根据name获得bean实例,如果在本工厂中没有找到bean则需要在父工厂中寻找 | Object | Object getBean(String name) throws BeansException; |
containsBean | 根据所给的name判断是否有对应的beandefinition,如果在本工厂实例中找不到对应的bean,那么就会去父工厂中寻找,3.陷阱出现:这边不管类是否抽象类,懒加载,是否在容器范围内,只要符合都返回true,所以这边true,不一定能从getBean获取实例 | boolean | boolean containsBean(String name) |
isSingleton | 判断获得的bean是否为单例实例,如果是,那么每次调用getBean返回的是同一个对象 | boolean | boolean isSingleton(String name) throws NoSuchBeanDefinitionException; |
getType | 根据name,获得对应bean的类型信息 | Class | Class getType(String name) throws NoSuchBeanDefinitionException; |
getAliases | 根据name,返回对应的bean的别名 | String[] | Sting[] getAliases(String name) |
isPrototype | 是否是prototype类型,这个属性可以由用户在BeanDefinition中指定 | boolean | boolean isPrototype(String name) |
(注:由上面一系列的接口方法,可以使用不同的Bean的检索方法,很方便的从Ioc容器中得到需要的bean)
BeanFactory的子接口有如下:
- ApplicationContext
- AutowireCapableBeanFactory
- ConfigurableApplicationContext
- ConfigurableBeanFactory
- ConfigurableListableBeanFactory
- ConfigurablePortletApplicationContext
- ConfigurableWebApplicationContext
- HierarchicalBeanFactory
- ListableBeanFactory
- WebApplicationContext
BeanFactory的直接或间接实现类有如下:
- AbstractApplicationContext,
- AbstractAutowireCapableBeanFactory,
- AbstractBeanFactory,
- AbstractRefreshableApplicationContext,
- AbstractRefreshableConfigApplicationContext,
- AbstractRefreshablePortletApplicationContext,
- AbstractRefreshableWebApplicationContext,
- AbstractXmlApplicationContext,
- AnnotationConfigApplicationContext,
- AnnotationConfigWebApplicationContext,
- ClassPathXmlApplicationContext,
- DefaultListableBeanFactory,
- FileSystemXmlApplicationContext,
- GenericApplicationContext,
- GenericWebApplicationContext,
- GenericXmlApplicationContext,
- ResourceAdapterApplicationContext,
- SimpleJndiBeanFactory,
- StaticApplicationContext,
- StaticListableBeanFactory,
- StaticPortletApplicationContext,
- StaticWebApplicationContext,
- XmlBeanFactory,
- XmlPortletApplicationContext,
- XmlWebApplicationContext
继承关系图:
BeanFactory:是IOC容器的核心接口, 它定义了IOC的基本功能,我们看到它主要定义了getBean方法。getBean方法是IOC容器获取bean对象和引发依赖注入的起点。方法的功能是返回特定的名称的Bean。
BeanFactory 是初始化 Bean 和调用它们生命周期方法的“吃苦耐劳者”。注意,BeanFactory 只能管理单例(Singleton)Bean 的生命周期。它不能管理原型(prototype,非单例)Bean 的生命周期。这是因为原型 Bean 实例被创建之后便被传给了客户端,容器失去了对它们的引用。
BeanFactory有着庞大的继承、实现体系,有众多的子接口、实现类。来看一下BeanFactory的基本类体系结构(接口为主):
BeanFactory接口体系
BeanFactory体系下主要可以分类两类,
基础BeanFactory的体系:主要包括
基础BeanFactory层级结构
- BeanFactory
- HierarchicalBeanFactory
- AutowireCapableBeanFactory
- ListableBeanFactory
- ConfigurableBeanFactory
- ConfigurableListableBeanFactory
另一类主要是继承自ApplicationContext的应用上下文接口:主要包括
ApplicationContext层级结构
- ApplicationContext
- ConfigurableApplicationContext
- WebApplicationContext
- ConfigurableWebApplicationContext
SpringIoc容器的主要接口按照层级划分
共分为4级,这4级接口是BeanFactory的基本接口体系
BeanFactory 定义了Ioc容器的基本规范,包括getBean这样的Ioc容器的基本方法(作为一个主接口不继承任何接口) BeanFactory是Spring Bean容器的根类,是容器最基本客户端试图。实现类应该尽可能地支持生命周期函数。
public interface BeanFactory {
// FactoryBean实例前缀
String FACTORY_BEAN_PREFIX = "&";
// 通过bean名称获取bean实例,无论是Singleton还是Prototype。
// 如果是name是别名,会解析为最终的真实名称。
// 如果在本BeanFactory没有找到实例,会询问父BeanFactory查找
// NoSuchBeanDefinitionException、BeansException
Object getBean(String name) throws BeansException;
// 与getBean(String name)基本相同,增加强制类型校验,如果类型异常抛出BeanNotOfRequiredTypeException
T getBean(String name, Class requiredType) throws BeansException;
// 通过给定的参数匹配构造函数或者工厂方法创建给定名称的实例。
Object getBean(String name, Object... args) throws BeansException;
// 按类型获取唯一bean,会涉及primary逻辑,priority逻辑
T getBean(Class requiredType) throws BeansException;
// 通过制定类型和参数,选择特定的构造函数或工厂方法,获取唯一对象。会涉及primary逻辑,priority逻辑
T getBean(Class requiredType, Object... args) throws BeansException;
// 返回指定类型的提供器,允许延迟后台检索实例,包括可用性和唯一性选项。
ObjectProvider getBeanProvider(Class requiredType);
// 返回匹配类型的实例,可以是泛型类型声明。注意与反射注入点不同,不支持集合类型。
// 为了以编程方式检索匹配特定类型的bean列表,请在这里指定实际的bean类型作为参数,
// 然后使用{@link ObjectProvider#orderedStream()}或它的延迟流/迭代选项
ObjectProvider getBeanProvider(ResolvableType requiredType);
// 当前BeanFactory是否包含bean定义或者以给定的name扩展注册的单例
// 如果给点的name是别名,会通过别名系统还原为最原始的bean名称
// 如果是HierarchicalBeanFactory,本BeanFactory没有找到,会从父BeanFactory查询
// 只要BeanDefiniton是定义了的,该方法都会返回ture,无论是concrete or abstract, lazy or eager, in scope or not。
// 因此,并不是本方法返回true就表示getBean就能成功地获取实例
boolean containsBean(String name);
// 如果给点的name是别名,会通过别名系统还原为最原始的bean名称
// 如果是HierarchicalBeanFactory,本BeanFactory没有找到,会从父BeanFactory查询
// 判断给定name的bean是否定义为单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
// 如果给点的name是别名,会通过别名系统还原为最原始的bean名称
// 如果是HierarchicalBeanFactory,本BeanFactory没有找到,会从父BeanFactory查询
// 判断给定name的bean是否定义为原型
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
// 检查具有给定名称的bean是否与指定的类型匹配。
// 更具体地说,检查给定名称的getBean调用是否会返回一个可分配给指定目标类型的对象。
// 如果给点的name是别名,会通过别名系统还原为最原始的bean名称
// 如果是HierarchicalBeanFactory,本BeanFactory没有找到,会从父BeanFactory查询
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
// 检查具有给定名称的bean是否与指定的类型匹配。
// 更具体地说,检查给定名称的getBean调用是否会返回一个可分配给指定目标类型的对象。
// 如果给点的name是别名,会通过别名系统还原为最原始的bean名称
// 如果是HierarchicalBeanFactory,本BeanFactory没有找到,会从父BeanFactory查询
boolean isTypeMatch(String name, Class> typeToMatch) throws NoSuchBeanDefinitionException;
// 推断指定name的bean的类型。更具体地说,返回getBean(name)对象的类型。
// 对于FactoryBean,返回的FactoryBean创建对象的类型,与FactoryBean#getObjectType()的结果相同
// 可能导致初始化之前为初始化的FactoryBean,参见getType(String, boolean)方法
// 如果给点的name是别名,会通过别名系统还原为最原始的bean名称
// 如果是HierarchicalBeanFactory,本BeanFactory没有找到,会从父BeanFactory查询
@Nullable
Class> getType(String name) throws NoSuchBeanDefinitionException;
// 与getType(string)相似,只是指定是否允许FactoryBean初始化
@Nullable
Class> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
// 返回指定名称的所有别名信息,如果name是别名,返回原始名和其他笔名,原始名在数组的第一个元素
// 如果是HierarchicalBeanFactory,本BeanFactory没有找到,会从父BeanFactory查询
String[] getAliases(String name);
}
有3个子接口继承了它,进行功能上的增强
HierarchiaclBeanFactory
ListableBeanFactory
AutowireCapableBeanFactory
详细介绍
HierarchiaclBeanFactory 扩展自BeanFactory,增加了层级结构管理的功能。通过ConfigurableBeanFactory接口中的setParentBeanFactory,允许配置父BeanFactory。
public interface HierarchicalBeanFactory extends BeanFactory {
// 返回当前BeanFactory的父BeanFactory,如果没有返回null
@Nullable
BeanFactory getParentBeanFactory();
// 返回本BeanFactory是否包含指定namne的bean,不考虑祖先BeanFactory
boolean containsLocalBean(String name);
}
ListableBeanFactory 扩展BeanFactory功能,支持枚举所有内部定义的Bean。如果是HierarchicalBeanFactory该接口的方法返回值将不会考虑祖先BeanFactory的层次结构,而是只包含本BeanFactory的信息,可以使用BeanFactoryUtils来考虑祖先类。
该接口中的方法将只尊重该工厂的bean定义。除了getBeanNamesForType和getBeansOfType之外,本接口中其他的方法不会考虑通过其他方式(例如ConfigurableBeanFactory的registerSingleton)注入的单例bean。
public interface ListableBeanFactory extends BeanFactory {
// 检查这个bean工厂是否包含具有给定名称的bean定义。
// 不考虑该工厂可能参与的任何层次结构,并忽略通过bean定义以外的其他方式注册的任何单例bean。
boolean containsBeanDefinition(String beanName);
// 返回本BeanFactory中BeanDefinition的数量
int getBeanDefinitionCount();
// 返回本BeanFactory中BeanDefinition的名称集合
String[] getBeanDefinitionNames();
// 返回指定bean的提供程序,允许按需惰性地检索实例,包括可用性和唯一性选项
// requiredType 必须匹配的类型,可以是父类或者接口
// allowEagerInit 基于流的访问,为了类型检查,是否可以初始化 ”延迟初始化的单例“
// 和 ”由FactoryBeans创建的对象“(或者由"factory-bean"指定的工厂方法)。
ObjectProvider getBeanProvider(Class requiredType, boolean allowEagerInit);
// 返回指定bean的提供程序,允许按需惰性地检索实例,包括可用性和唯一性选项
// requiredType 必须匹配的类型,可以是泛型类型声明
// 注意:与反射注入点不同,这里不支持集合类型。为了以编程方式检索匹配特定类型的bean列表,
// 在这里指定实际的bean类型作为参数,然后使用ObjectProvider#orderedStream()或它的延迟流/迭代选项
// allowEagerInit 基于流的访问,为了类型检查,是否可以初始化 ”延迟初始化的单例“
// 和 ”由FactoryBeans创建的对象“(或者由"factory-bean"指定的工厂方法)。
ObjectProvider getBeanProvider(ResolvableType requiredType, boolean allowEagerInit);
// 返回与给定类型及子类匹配的bean的名称,根据bean定义或FactoryBeans.getObjectType的值进行判断。
// 注意:该方法只检查顶级bean,它也不检查可能与指定类型匹配的嵌套bean。
// 考虑由FactoryBeans创建的对象,这意味着FactoryBeans将被初始化。
// 如果FactoryBean创建的对象不匹配,则原始的FactoryBean本身将与类型匹配
// 不考虑该工厂层次结构。可以使用BeanFactoryUtils的beanNamesForTypeIncludingAncestors包括祖先
// 注意:不要忽略通过bean定义以外的其他方式注册的单例bean。
// 该版本的getBeanNamesForType匹配所有种类的bean,包括单例、原型和FactoryBean。
// 在大多数是实现中与getBeanNamesForType(type, true, true)的结果相同。
// 返回的beanName的顺序应该尽可能地与后台定义的顺序相同。
String[] getBeanNamesForType(ResolvableType type);
// includeNonSingletons 是否也包含原型bean或范围内的bean,还是只包含单例(也适用于工厂bean)
// allowEagerInit 是否初始化FactoryBean。如果为false,那么匹配的是只check相应的FactoryBean
// type 泛型类或者接口
String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);
// type null表示返回所有的bean名称
String[] getBeanNamesForType(@Nullable Class> type);
String[] getBeanNamesForType(@Nullable Class> type, boolean includeNonSingletons, boolean allowEagerInit);
// type 泛型类或者接口,null表示获取所有
Map getBeansOfType(@Nullable Class type) throws BeansException;
Map getBeansOfType(@Nullable Class type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
// 找到所有用提供的Annotation类型注释的bean的名称,而不创建相应的bean实例
// 考虑由FactoryBeans创建的对象,这意味着FactoryBeans将被初始化。
// 如果FactoryBean创建的对象不匹配,则原始的FactoryBean本身将与类型匹配
// annotationType 要查找的注释类型(在指定bean的类、接口或工厂方法级别)
String[] getBeanNamesForAnnotation(Class extends Annotation> annotationType);
Map getBeansWithAnnotation(Class extends Annotation> annotationType) throws BeansException;
// 在指定的bean上找到一个annotationType的注释,
// 如果在给定的类本身上找不到注释,则遍历它的接口和超类,并检查bean的工厂方法(如果有的话)
// beanName 要在上面查找注释的bean的名称
@Nullable
A findAnnotationOnBean(String beanName, Class annotationType)
throws NoSuchBeanDefinitionException;
}
AutowireCapableBeanFactory是对BeanFactory的扩展,主要增加了自动装配Bean属性依赖的能力。提供多种自动装配策略和细粒度控制装配过程的方法。
// 扩展自动装配功能,常引用与框架集成代码中,用于控制Spring无法控制的现有Bean。
// 注意ApplicationContext未实现该接口,因为应用程序极少用到该类。
// 可以通过ApplicationContext的getAutowireCapableBeanFactory获取到该类实例
// 也可以通过BeanFactoryAware来访问,通过将BeanFactory转换
public interface AutowireCapableBeanFactory extends BeanFactory {
// 常量,指示没有外部定义的自动装配。
// 请注意,BeanFactoryAware等和注释驱动的注入仍然会被应用。
int AUTOWIRE_NO = 0;
// 常量,表示通过name注入bean属性
int AUTOWIRE_BY_NAME = 1;
// 常量,表示通过type注入bean属性
int AUTOWIRE_BY_TYPE = 2;
// 常量,表示通过满足最贪婪构造函数的方式注入(包括解析适当的构造函数)
int AUTOWIRE_CONSTRUCTOR = 3;
// 弃用常量,表明通过bean的类自省推断适当的注入策略
@Deprecated
int AUTOWIRE_AUTODETECT = 4;
// 该属性是一种约定俗成的用法:以类全限定名+.ORIGINAL 作为Bean Name
// 用于告诉Spring,在初始化的时候,需要返回原始给定实例,而别返回代理对象
// initializeBean(Object, String)
// applyBeanPostProcessorsBeforeInitialization(Object, String)
// applyBeanPostProcessorsAfterInitialization(Object, String)
String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
//-----------------------------------------------
// 用于创建和填充外部bean实例的典型方法
//-----------------------------------------------
// 完全创建一个值得类的新实例。并执行完的全部初始化,包括所有可用的BeanPostProcessor
// 注意: 这个方法的目的是创建实例,填充注解的字段和方法,以及执行所有的初始化回调。
// 但是并不会执行按name和按类型装配的属性,要达到此目的可以使用createBean(Class, int, boolean)
T createBean(Class beanClass) throws BeansException;
// 通过应用初始化后置回调和bean属性后置处理来填充给定的bean实例。
// 注意:这本质上是为了重新填充注解字段和方法,无论是创建新实例还是反序列化实例。
// 它并不意味着传统的按名称或按类型自动装配属性;使用autowireBeanProperties实现这些目的。
void autowireBean(Object existingBean) throws BeansException;
// 配置给定的原始bean:自动装配bean属性、应用bean属性值、应用setBeanName和setBeanFactory等工厂回调,
// 还应用所有BeanPostProcessor(包括包装给定生bean的处理器)。
// 是initializeBean方法的超集,完全应用了相应BeanDefinition指定的配置
// 注意:该方法需要给定name的BeanDefinition
Object configureBean(Object existingBean, String beanName) throws BeansException;
//-----------------------------------------------
// 用于对bean生命周期进行细粒度控制的专门方法
//-----------------------------------------------
// 完全创建一个新bean,参见createBean(class)。本质上是autowire的超集,增加了initializeBean行为。
// 支持所有的自动装配策略,并能够控制进行依赖检查。dependencyCheck不适用于构造函数自动装配(循环依赖)
Object createBean(Class> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
// 使用指定的装配策略实例化给定类的实例。支持所有的策略,使用AUTOWIRE_NO时只应用实例化之前回调。
// 不应用标准BeanPostProcessor回调,也不执行进一步的Bean初始化。
// 如果适用于实例构造,InstantiationAwareBeanPostProcessor回调将被应用。
Object autowire(Class> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
// 根据名称或类型自动装配给定bean实例的bean属性。使用AUTOWIRE_NO时只应用实例化之前回调。
// 不应用标准BeanPostProcessor回调,也不执行进一步的Bean初始化。
// 如果适用于实例构造,InstantiationAwareBeanPostProcessor回调将被应用。
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
// 将具有给定名称的bean定义的属性值,应用到给定的bean实例。
// 该方法不会自动装配bean属性;只应用显式定义的属性值。可以使用autowireBeanProperties自动装配
// 注意: beanName指定的BeanDefinition需要存在。
// 不应用标准BeanPostProcessor回调,也不执行进一步的Bean初始化。
// 如果适用于实例构造,InstantiationAwareBeanPostProcessor回调将被应用。
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
// 初始化给定的原始bean,应用工厂回调函数(例如setBeanName和setBeanFactory),
// 应用所有BeanPostProcessor(包括包装给定生bean的处理器)。
// 注意: 给定名称bean定义,可以不存在。传入的bean名称只是用于回调,不会根据注册的bean定义进行检查。
// 可以通过ORIGINAL_INSTANCE_SUFFIX返回原始的bean,而不是返回wrap bean
Object initializeBean(Object existingBean, String beanName) throws BeansException;
// 对存在的bean, 应用BeanPostProcessor的postProcessBeforeInitialization方法
// 支持ORIGINAL_INSTANCE_SUFFIX返回原始对象
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
// 对存在的bean, 应用BeanPostProcessor的postProcessAfterInitialization方法
// 支持ORIGINAL_INSTANCE_SUFFIX返回原始对象
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
// 销毁给定的bean实例(通常来自createBean),
// 应用DisposableBean契约以及注册的DestructionAwareBeanPostProcessors。
// 在销毁过程中出现的任何异常都应该被捕获并记录下来,而不是传播给该方法的调用者。
void destroyBean(Object existingBean);
//-----------------------------------------------
// 用于解析注入点的代理方法
//-----------------------------------------------
// 解析唯一匹配给定对象类型(如果有的话)的bean实例,包括它的bean名称。
// 这实际上是getBean(Class)的一个变体,它保留了匹配实例的bean名。
NamedBeanHolder resolveNamedBean(Class requiredType) throws BeansException;
// 为给定的bean名称解析一个bean实例,为目标工厂方法公开提供一个依赖描述符。
// 这实际上是getBean(String, Class)的一个变体,它支持带有InjectionPoint参数的工厂方法。
Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
// 根据这个工厂中定义的bean解析指定的依赖项。如果没有返回null
// descriptor: 依赖的描述符(字段/方法/构造函数)
// requestingBeanName: 声明给定依赖项的bean的名称
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
// 根据这个工厂中定义的bean解析指定的依赖项。如果没有返回null
// descriptor: 依赖的描述符(字段/方法/构造函数)
// requestingBeanName: 声明给定依赖项的bean的名称
// autowiredBeanNames: 将符合自动装配条件的所有bean(用于解析给定依赖项)的名称添加到其中的集合
// typeConverter: 用于填充数组和集合的类型转换器
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
}
ConfigurableBeanFactory 扩展自HierarchicalBeanFactory和SingletonBeanRegistry。由大多数bean工厂实现的配置接口。除了BeanFactory接口中的客户端方法之外,还提供配置BeanFactory的工具。
这个BeanFactory接口并不意味着要在普通的应用程序代码中使用: 对于一般需求,请使用BeanFactory或ListableBeanFactory。这个接口只是为了在需要访问bean工厂配置方法时允许框架内部的即插即用。
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
// 自定义的scope可以通过registerScope添加
// 常量,标准单例Scope标志
String SCOPE_SINGLETON = "singleton";
// 常量,标准原型Scope标志
String SCOPE_PROTOTYPE = "prototype";
// 设置父BeanFactory
// 注意,父类不能更改: 只有在工厂实例化时不可用时,才应该在构造函数外部设置父类
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
// 设置用于装载bean类的ClassLoader。默认是线程上下文类装入器。
// 请注意,这个类装入器将只应用于尚未携带解析的bean类的bean定义。
// 默认情况下,Spring 2.0是这样的:Bean定义只携带Bean类名,在工厂处理Bean定义时进行解析
void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
// 返回ClassLoader, 如果连系统类加载器都不可访问,则只有返回null。
@Nullable
ClassLoader getBeanClassLoader();
// 指定用于类型匹配的临时类加载器。默认值是none,使用标准bean类加载器即可。
// 临时类加载器,通常仅用于“加载时编织”,以尽可能地延迟真实类的加载。
// 一旦BeanFactory完成了它的引导阶段,临时类加载就会被移除
void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
// 如果有临时类加载器,则返回用于类型匹配的临时类加载器。
@Nullable
ClassLoader getTempClassLoader();
// 设置是否缓存bean元数据,比如给定的bean定义(以合并的方式)和已解析的bean类。默认的是。
// 关闭此标志以启用bean定义对象和特定bean类的热刷新。
// 如果这个标志是关闭的,任何bean实例的创建都将为新解析的类重新查询bean类装入器。
void setCacheBeanMetadata(boolean cacheBeanMetadata);
boolean isCacheBeanMetadata();
// 为bean定义值中的表达式指定解析策略。默认情况下,BeanFactory中没有活跃的表达式支持。
// ApplicationContext通常会在这里设置一个标准的表达式策略,支持“#{…}"的统一EL兼容风格表达式。
void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
@Nullable
BeanExpressionResolver getBeanExpressionResolver();
// 指定一个用于转换属性值的ConversionService,作为JavaBean中PropertyEditor的替代。
void setConversionService(@Nullable ConversionService conversionService);
@Nullable
ConversionService getConversionService();
// 添加一个PropertyEditorRegistrar,以应用于所有bean创建过程。
// 这样的注册表创建新的PropertyEditor并注册到注册表,对于每个bean的创建请求都是全新可见的。
// 这样可以避免自定义PropertyEditor的同步,通常比使用registerCustomEditor更加可取
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
// 为给定类型的所有属性注册给定的自定义属性编辑器。在工厂配置时调用。
// 注意,这个方法将注册一个共享的自定义编辑器实例;为了线程安全,对该实例的访问将被同步。
// 通常最好使用addPropertyEditorRegistrar来代替这个方法,以避免在自定义编辑器上需要同步。
void registerCustomEditor(Class> requiredType, Class extends PropertyEditor> propertyEditorClass);
// 使用已经注册到这个BeanFactory的自定义编辑器初始化给定的PropertyEditorRegistry。
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
// 设置一个自定义类型转换器,BeanFactory应该使用它来转换bean属性值、构造函数参数值等。
// 这将覆盖默认的PropertyEditor机制,从而使任何自定义编辑器或自定义编辑器注册器变得无关紧要。
void setTypeConverter(TypeConverter typeConverter);
// 获取此BeanFactory使用的类型转换器。对于每次调用都可能是新实例,因为TypeConverter通常不是线程安全的。
// 如果默认的PropertyEditor机制是活动的,则返回的TypeConverter将知道所有已注册的自定义编辑器。
TypeConverter getTypeConverter();
// 为内置的值(如注释属性)添加字符串解析器。
void addEmbeddedValueResolver(StringValueResolver valueResolver);
// 确定嵌入值解析器是否已注册到此bean工厂,并将通过resolveEmbeddedValue(String)应用。
boolean hasEmbeddedValueResolver();
// 解析给定的嵌入值,例如一个注释属性。
@Nullable
String resolveEmbeddedValue(String value);
// 添加一个新的BeanPostProcessor,它将应用于这个工厂创建的bean。在工厂配置时调用。
// 注意:此处提交的后处理程序将按注册顺序调用;通过实现Ordered接口表示的任何排序语义都将被忽略。
// 注意:自动检测的后处理器(例如ApplicationContext中的bean)将始终应用在以编程方式注册的后处理器之后。
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
// 如果有的话,返回当前注册的BeanPostProcessors数量。
int getBeanPostProcessorCount();
// 注册给定的作用域,由给定的作用域实现支持。
void registerScope(String scopeName, Scope scope);
// 返回所有当前注册的作用域的名称。
// 这将只返回显式注册的作用域的名称。诸如“singleton”和“prototype”这样的内置作用域将不会暴露。
String[] getRegisteredScopeNames();
// 返回给定作用域名的作用域实现(如果有的话)。
// 这将只返回显式注册的作用域。诸如“singleton”和“prototype”这样的内置作用域将不会暴露。
@Nullable
Scope getRegisteredScope(String scopeName);
// 为这个bean工厂设置ApplicationStartup。这允许应用程序上下文在应用程序启动期间记录度量。
void setApplicationStartup(ApplicationStartup applicationStartup);
// 获取该BeanFactory的ApplicationStartup
ApplicationStartup getApplicationStartup();
// 提供与此工厂相关的安全访问控制上下文。
AccessControlContext getAccessControlContext();
// 从给定的其他工厂复制所有相关配置。
// 应该包括所有标准配置设置以及BeanPostProcessors、作用域和特定于工厂的内部设置。
// 不应该包括实际bean定义的任何元数据,比如BeanDefinition对象和bean名称别名。
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
// 给定一个bean名称,创建一个别名。我们通常使用这个方法来支持XML中IDs非法的名称(用于bean名称)。
// 通常在工厂配置期间调用,但也可以用于别名的运行时注册。因此,工厂实现应该同步别名访问。
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
// 解析在此工厂中注册的所有别名目标名称和别名,并对它们应用给定的StringValueResolver。
// 例如,值解析器可以解析目标bean名称甚至别名中的占位符。
void resolveAliases(StringValueResolver valueResolver);
// 返回给定bean名称的合并bean定义,必要时将子bean定义与其父bean定义合并。也考虑祖先工厂中的bean定义
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 确定具有给定名称的bean是否为FactoryBean。false表示该bean存在,但不是FactoryBean。
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
// 显式控制指定bean的当前创建状态。仅供容器内部使用。
void setCurrentlyInCreation(String beanName, boolean inCreation);
// 返回指定的bean当前是否正在创建中。
boolean isCurrentlyInCreation(String beanName);
// 为给定bean注册一个依赖bean,在销毁给定bean之前销毁它。beanName 依赖 dependentBeanName
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,包括已注册Disposable的内部bean。在关闭BeanFactory的时候被调用。
// 在销毁过程中出现的任何异常都应该被捕获并记录下来,而不是传播给该方法的调用者。
void destroySingletons();
}
ConfigurableListableBeanFactory 是一个更强大的接口,继承了上述的所有接口,无所不包。扩展自ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory三个接口。提供了分析和修改bean定义以及预实例化单例的工具。这个接口普通应用基本不适用,只是为了在需要访问bean工厂配置方法时允许框架内部的即插即用。
public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
// 忽略自动装配的依赖类型:例如,String。默认是没有的。
void ignoreDependencyType(Class> type);
// 忽略自动装配的依赖接口。
// 这通常会被应用程序上下文用来注册以其他方式解析的依赖项,
// 比如通过BeanFactoryAware解析BeanFactory,或者通过ApplicationContextAware解析ApplicationContext
// 默认情况下,只有BeanFactoryAware接口被忽略。对于要忽略的其他类型,请为每种类型调用此方法。
void ignoreDependencyInterface(Class> ifc);
// 用相应的自动连接值注册一个特殊的依赖类型。
// 这是为工厂/上下文引用准备的,这些引用被认为是可自动装配的,但没有定义为工厂中的bean:
// 例如,一个ApplicationContext类型的依赖被解析为bean所在的ApplicationContext实例。
// 注意:在普通BeanFactory中没有注册这样的默认类型,甚至对于BeanFactory接口本身也没有。
// dependencyType:要注册的依赖类型。这通常是一个基本接口,比如BeanFactory,
// 如果声明为自动装配依赖项(例如ListableBeanFactory),子类也会解析,只要给定的值实际实现了扩展的接口。
// autowiredValue:相应的自动装配值。这也可能是ObjectFactory接口的一个实现,它允许延迟解析实际的目标值。
void registerResolvableDependency(Class> dependencyType, @Nullable Object autowiredValue);
// 确定指定的bean是否符合自动装配候选条件,以便被注入到声明匹配类型依赖的其他bean中。这个方法也检查祖先工厂。
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException;
// 返回指定bean的注册BeanDefinition,允许访问其属性值和构造函数参数值(可以在BeanFactory后处理期间修改)。
// 返回的BeanDefinition对象不应该是副本,而是原始对象。当然如果有必要,它应该可以转换为更具体的实现类型。
// 注意:这个方法不考虑祖先工厂。它仅用于访问该工厂的本地bean定义。
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 返回该工厂管理的所有bean名称的统一视图。包括bean定义名称以及手动注册的单例实例名称,
// bean定义名称始终放在首位,类似于特定于类型/注释的bean名称检索的工作方式。
Iterator getBeanNamesIterator();
// 清除合并的bean定义缓存,删除被认为还不符合完整元数据缓存条件的bean条目。
// 通常在更改原始bean定义后触发,例如在应用BeanFactoryPostProcessor之后。
// 请注意,此时已经创建的bean的元数据将被保留。
void clearMetadataCache();
// 冻结所有bean定义,表明已注册的bean定义不再被修改或进一步后处理。
// 这允许工厂主动缓存bean定义元数据。
void freezeConfiguration();
// 返回此工厂的bean定义是否被冻结,即不应该被进一步修改或后处理。
boolean isConfigurationFrozen();
// 确保所有非lazy-init单例都被实例化,还要考虑FactoryBean。通常在工厂设置结束时调用,如果需要的话。
// 这可能使工厂中的一些bean被初始化!在这种情况下,可以调用destroySingleton()来完全清除。
void preInstantiateSingletons() throws BeansException;
}
(这4级接口是BeanFactory的基本接口体系。继续,下面是继承关系的2个抽象类和2个实现类)
抽象类:
AbstractBeanFactory 作为一个抽象类,实现了三级接口ConfigurableBeanFactory大部分功能。
AbstractAutowireCapableBeanFactory 同样是抽象类,继承自AbstractBeanFactory,并额外实现了二级接口AutowireCapableBeanFactory
实现类:
DefaultListableBeanFactory继承自AbstractAutowireCapableBeanFactory,实现了最强大的四级接口ConfigurableListableBeanFactory,并实现了一个外来接口BeanDefinitionRegistry,它并非抽象类。
最后是最强大的XmlBeanFactory,继承自DefaultListableBeanFactory,重写了一些功能,使自己更强大。
ApplicationContext 扩展自EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver等接口,是为应用程序提供配置的中央接口。在应用程序运行时,该接口实例是只读的,但是如果实现支持,也是可以重新加载的。
ApplicationContext提供如下功能:
1、用于访问应用程序组件的Bean工厂方法。继承自ListableBeanFactory。
2、以通用方式加载文件资源的能力。继承自ResourceLoader接口。
3、能够将事件发布到已注册的监听器。继承自ApplicationEventPublisher接口。
4、具有消息解析能力,支持国际化。继承自MessageSource接口。
5、子上下文能够从父上下文继承定义,并能够重写父定义。这意味着单个父上下文可以被整个web应用程序使用,而每个servlet都有自己独立于任何其他servlet的子上下文。
除了标准的BeanFactory生命周期功能外,ApplicationContext实现还检测并调用ApplicationContextAware 、ResourceLoaderAware、ApplicationEventPublisherAware和MessageSourceAware的相应setXXX方法。如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的躯体了,ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置实现。
BeanFactorty接口提供了配置框架及基本功能,但是无法支持spring的aop功能和web应用。而ApplicationContext接口作为BeanFactory的派生,因而提供BeanFactory所有的功能。而且ApplicationContext还在功能上做了扩展,相较于BeanFactorty,ApplicationContext还提供了以下的功能:
(1)MessageSource, 提供国际化的消息访问
(2)资源访问,如URL和文件
(3)事件传播特性,即支持aop特性
(4)载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层ApplicationContext:是IOC容器另一个重要接口, 它继承了BeanFactory的基本功能, 同时也继承了容器的高级功能,如:MessageSource(国际化资源接口)、ResourceLoader(资源加载接口)、ApplicationEventPublisher(应用事件发布接口)等。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
// 返回应用上下问的ID
@Nullable
String getId();
// 返回部署的应用程序的应用名
String getApplicationName();
// 返回上下的显示名称,永远不为null
String getDisplayName();
// 返回此上下文第一次加载的时间戳
long getStartupDate();
// 返回词应用上下文的父上下文,如果返回null表示该上下文无父应用上下文
@Nullable
ApplicationContext getParent();
// 为此上下文公开AutowireCapableBeanFactory功能。
// 这通常不被应用程序代码使用,除非用于初始化生活在应用程序上下文之外的bean实例,将Spring bean生命周期(完全或部分)应用到它们。
// 另外,ConfigurableApplicationContext接口公开的内部BeanFactory也提供了对AutowireCapableBeanFactory接口的访问。
// 目前的方法主要作为ApplicationContext接口上的一个方便的、特定的工具。
// 注意:从4.2开始,这个方法将在应用程序上下文关闭后持续抛出IllegalStateException。
// 在当前Spring框架版本中,只有可刷新的应用程序上下文是这样的;从4.2开始,所有的应用程序上下文实现都必须遵守。
// 不支持AutowireCapableBeanFactory接口,不拥有AutowireCapableBeanFactory,或者上下文已经被关闭了,将抛出IllegalStateException异常
// 参见:ConfigurableApplicationContext的refresh 和 ConfigurableApplicationContext的getBeanFactory
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
ConfigurableApplicationContext 扩展自ApplicationContext, Lifecycle, Closeable接口。大部分(如果不是全部)应用程序上下文都要实现的SPI接口。除了ApplicationContext接口中的应用程序上下文客户端方法之外,还提供配置应用程序上下文的工具。
这里封装了配置和生命周期方法,以避免使它们对ApplicationContext客户端代码显得明显。目前的方法应该只用于启动和关闭代码。
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
// 这些字符的任意数量都被认为是单个字符串值中的多个上下文配置路径之间的分隔符。
// AbstractXmlApplicationContext#setConfigLocation ContextLoader#CONFIG_LOCATION_PARAM FrameworkServlet#setContextConfigLocation
String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
// 工厂中的converonservice bean的名称。如果没有提供,则应用默认转换规则。
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
// 工厂中LoadTimeWeaver的bean名称。如果提供了这样的bean,那么上下文将使用临时类加载器进行类型匹配,以便允许LoadTimeWeaver处理所有实际bean类。
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
// 工厂中Environment的bean名称
String ENVIRONMENT_BEAN_NAME = "environment";
// 工厂中System属性properties的bean名称
String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
// 工厂中系统环境变量的bean名称
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
// 工厂中ApplicationStartup的bean名称
String APPLICATION_STARTUP_BEAN_NAME = "applicationStartup";
// shutdown hook线程的名称
String SHUTDOWN_HOOK_THREAD_NAME = "SpringContextShutdownHook";
// 设置应用上下文的唯一ID
void setId(String id);
// 设置此应用程序上下文的父类。
// 注意,不应该更改父类:当创建该类对象不可用时,才应该在构造函数外部设置父类,例如WebApplicationContext
void setParent(@Nullable ApplicationContext parent);
// 设置应用上下文的Environment
void setEnvironment(ConfigurableEnvironment environment);
// 以可配置的形式返回此应用程序上下文的Environment,允许进一步定制。
@Override
ConfigurableEnvironment getEnvironment();
// 设置此应用上下文的ApplicationStartup。以允许应用上下文记录启动过程中的度量信息。
void setApplicationStartup(ApplicationStartup applicationStartup);
// 获取此应用上下文的ApplicationStartup
ApplicationStartup getApplicationStartup();
// 添加一个新的BeanFactoryPostProcessor,它将在刷新时,在计算任何bean定义之前,应用到该应用程序上下文的内部bean工厂。在上下文配置期间调用。
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);
// 添加一个新的ApplicationListener,它将在上下文事件(如上下文刷新和上下文关闭)时得到通知。
// 注意,这里注册的任何ApplicationListener都将在刷新时应用,如果上下文还没有激活; 或者在上下文已经激活的情况下使用当前事件多播。
void addApplicationListener(ApplicationListener> listener);
// 指定用于加载类路径资源和bean类的类加载器。
// 这个上下文类装入器将被传递给内部bean工厂。
void setClassLoader(ClassLoader classLoader);
// 将给定的协议解析器注册到这个应用程序上下文中,允许处理额外的资源协议。
// 任何此类解析器都将在此上下文的标准解析规则之前被调用。因此,它也可以覆盖任何默认规则。
void addProtocolResolver(ProtocolResolver resolver);
// 加载或刷新配置的持久表示,这些表示可能来自基于java的配置、XML文件、属性文件、关系数据库模式或其他格式。
// 因为这是一个启动方法,它应该销毁已经创建的单例,如果它失败了,以避免悬浮资源。
// 换句话说,在调用这个方法之后,要么实例化所有的单例,要么根本不实例化单例。
void refresh() throws BeansException, IllegalStateException;
// 向JVM运行时注册一个关闭钩子,在JVM关闭时关闭这个上下文,除非那时它已经关闭了。
// 这个方法可以被多次调用。每个上下文实例只会注册一个shutdown钩子(最大)。
// 从Spring5.2开始,关闭钩子线程的name应该是SHUTDOWN_HOOK_THREAD_NAME(SpringContextShutdownHook)。
void registerShutdownHook();
// 关闭此应用程序上下文,释放实现可能持有的所有资源和锁。这包括销毁所有缓存的单例bean。
// 注意:不要在父上下文上调用close;父上下文有自己独立的生命周期。
// 这个方法可以多次调用而不会产生副作用:对已经关闭的上下文的后续close调用将被忽略。
@Override
void close();
// 确定此应用程序上下文是否处于活动状态,也就是说,它是否至少刷新了一次并且尚未关闭。
boolean isActive();
// 返回这个应用程序上下文的内部bean工厂。可以用于访问底层工厂的特定功能。
// 注意:不要使用它来后期处理bean工厂;单例对象在之前已经被实例化了。
// 在处理bean之前,使用BeanFactoryPostProcessor拦截BeanFactory设置过程。
// 通常,这个内部工厂只有在上下文处于活动状态时才可以访问,也就是说,在refresh()和close()之间。
// isActive()标志可以用来检查上下文是否处于适当的状态。
ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}
ConfigurableWebApplicationContext 继承自WebApplicationContext和ConfigurableApplicationContext。由可配置的web应用程序上下文实现。由ContextLoader和FrameworkServlet支持。
注意:在调用从ConfigurableApplicationContext继承的refresh方法之前,需要调用该接口的set方法。它们自己不会导致上下文的初始化
public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {
// 用上下文路径 和/或 servlet名称 的ApplicationContext id的前缀。
String APPLICATION_CONTEXT_ID_PREFIX = WebApplicationContext.class.getName() + ":";
// 此工厂中ServletConfig环境bean的名称
String SERVLET_CONFIG_BEAN_NAME = "servletConfig";
// 为此Web应用上下文设置ServletContext。不会导致上下文初始化:所有配置属性设置后需要调用refresh
void setServletContext(@Nullable ServletContext servletContext);
// 为这个web应用程序上下文设置ServletConfig。
// 仅被特定Servlet的WebApplicationContext调用。
void setServletConfig(@Nullable ServletConfig servletConfig);
// 如果有的话,返回此web应用程序上下文的ServletConfig。
@Nullable
ServletConfig getServletConfig();
// 为这个web应用程序上下文设置名称空间,用于构建默认上下文配置位置。根web应用程序上下文没有名称空间。
void setNamespace(@Nullable String namespace);
// 返回此web应用程序上下文的名称空间(如果有的话)。
@Nullable
String getNamespace();
// 以init-param风格设置此web应用程序上下文的配置位置。例如使用逗号、分号或空格分隔的不同位置。
// 如果没有设置,则假定具体实现为给定的名称空间或根web应用程序上下文使用默认值。
void setConfigLocation(String configLocation);
// 设置此web应用程序上下文的配置位置。
// 如果没有设置,则假定实现为给定的名称空间或根web应用程序上下文使用默认值。
void setConfigLocations(String... configLocations);
// 返回此web应用程序上下文的配置位置,如果没有指定,则返回null。
@Nullable
String[] getConfigLocations();
}
二者区别
1.BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的Spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。 相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
BeanFacotry延迟加载,如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常;而ApplicationContext则在初始化自身是检验,这样有利于检查所依赖属性是否注入;所以通常情况下我们选择使用 ApplicationContext。
应用上下文则会在上下文启动后预载入所有的单实例Bean。通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。
2.BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。(Applicationcontext比 beanFactory 加入了一些更好使用的功能。而且 beanFactory 的许多功能需要通过编程实现而 Applicationcontext 可以通过配置实现。比如后处理 bean , Applicationcontext 直接配置在配置文件即可而 beanFactory 这要在代码中显示的写出来才可以被容器识别。 )
3.beanFactory主要是面对与 spring 框架的基础设施,面对 spring 自己。而 Applicationcontex 主要面对与 spring 使用的开发者。基本都会使用 Applicationcontex 并非 beanFactory 。
四、总结
作用:
1. BeanFactory负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。
2. ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能:
a. 国际化支持
b. 资源访问:Resource rs = ctx. getResource(“classpath:config.properties”), “file:c:/config.properties”
c. 事件传递:通过实现ApplicationContextAware接口
3. 常用的获取ApplicationContext