首先我们看一个大致的类图:
在SpringFramework IoC核心的设计中,我们可以看到两个主要的容器系列:一个是实现了BeanFactory的简单容器系列,这类容器提供最基础的IoC容器的功能;一个是实现了ApplicationContext接口的应用上下文,它作为高级形态的IoC容器 ①,提供了很多面向应用的、BeanFactory不具备的新特性。
一、BeanFactory(基础容器)
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
// 根据类型获取Bean
<T> T getBean(Class<T> requiredType) throws BeansException;
// 根据名称获取Bean
Object getBean(String name) throws BeansException;
// 根据名称+类型获取Bean
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
// 根据名称+参数获取Bean
Object getBean(String name, Object... args) throws BeansException;
// 是否含有指定名称的Bean
boolean containsBean(String name);
// 是否是Singleton类型的Bean
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
// 是否是Prototype类型的Bean
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
// 是否匹配name+类型
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
// 获取指定名称的Bean的Class类型
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
// 获取指定名称的Bean的别名数组
String[] getAliases(String name);
}
BeanFactory接口作为顶层设计,它定义了IoC容器的基本形态,提供了IoC容器应该遵守的最底层和最基本的服务契约。
BeanFactory接口最主要的设计是,提供了框架内获取托管Bean的主要API —— getBean方法。
基础IoC系列容器与其它接口、抽象类、实现类之间的关系:
- AutowireCapableBeanFactory(装配规则IoC)
public interface AutowireCapableBeanFactory extends BeanFactory {
int AUTOWIRE_NO = 0;
int AUTOWIRE_BY_NAME = 1;
int AUTOWIRE_BY_TYPE = 2;
int AUTOWIRE_CONSTRUCTOR = 3;
@Deprecated
int AUTOWIRE_AUTODETECT = 4;
//--------------------- 装配Bean实例相关的方法 ---------------------
// 根据Class创建Bean实例
<T> T createBean(Class<T> beanClass) throws BeansException;
// 重新填充这个Bean实例注释的字段和方法
void autowireBean(Object existingBean) throws BeansException;
// 根据相应的Bean定义装配这个未加工的Object,这实际上是initializeBean方法的超集
Object configureBean(Object existingBean, String beanName) throws BeansException;
// 分析Bean实例指定的依赖关系
Object resolveDependency(DependencyDescriptor descriptor, String beanName)
throws BeansException;
//--------------------- Bean实例生命周期相关的方法 ---------------------
// 根据指定的类型和装配策略,构造一个新的Bean实例,这实际上autowire方法的超集
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;
// 根据指定名称的Bean属性值应用于给定的Bean实例
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;
// 分析Bean实例指定的依赖关系
Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String>
autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
}
AutowireCapableBeanFactory接口主要提供Bean的自动装配规则和初始化能力,其抽象子类AbstractAutoWireCapableBeanFactory,实现了createBean()、autowireBean()和configureBean()方法,封装了初始化Bean的装配逻辑。
AbstractAutoWireCapableBeanFactory内部维护的一些成员变量:
1)allowCircularReferences:是否尝试自动解决bean之间的循环引用,默认为true;
2)allowRawInjectionDespiteWrapping:在循环引用的情况下,是否尝试注入原始bean实例,默认为false;
3)ignoredDependencyTypes:忽略依赖关系检查和自动装配的类型白名单,默认为无;
4)ignoredDependencyInterfaces:忽略依赖关系检查和自动装配的接口白名单,默认只有BeanFactory接口被忽略;
5)factoryBeanInstanceCache:未完成的FactoryBean实例缓存;
FactoryBean name --> BeanWrapper6)filteredPropertyDescriptorsCache:缓存过滤的属性描述符
bean Class -> PropertyDescriptor array
- ListableBeanFactory(清单IoC)
public interface ListableBeanFactory extends BeanFactory {
// 是否包含指定的Bean定义
boolean containsBeanDefinition(String beanName);
// 放回定义的Bean数目
int getBeanDefinitionCount();
// 返回定义的所有Bean名称
String[] getBeanDefinitionNames();
// 跟据Bean类型获取bean,它不会检查嵌套的FactoryBean创建的bean
String[] getBeanNamesForType(ResolvableType type);
String[] getBeanNamesForType(Class<?> type);
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons,
boolean allowEagerInit) throws BeansException;
// 根据注解查找相关BeanName数组
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
// 根据注解查找相关Bean Map
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
throws BeansException;
// 查找一个Bean上的注解
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
}
ListableBeanFactory接口,可以像清单一样列出该BeanFactory可以生产的所有Bean实例,它的子类DefaultListableBeanFactory和AbstractApplicationContext是初始化Bean的核心。
- HierarchicalBeanFactory(分层IoC)
public interface HierarchicalBeanFactory extends BeanFactory {
// 返回父工厂
BeanFactory getParentBeanFactory();
// 是否包含指定名称的Bean
boolean containsLocalBean(String name);
}
HierarchicalBeanFactory接口表示IoC容器的分层结构。它比较简单,主要是提供获取父BeanFactory的功能,比如让当前的BeanFactory加载父BeanFactory加载的Bean定义,弥补ListableBeanfactory欠缺的功能。
- ConfigurableBeanFactory(配置IoC)
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
// 设置父BeanFactory
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
// 以下四个:设置和获取BeanClassLoader
void setBeanClassLoader(ClassLoader beanClassLoader);
ClassLoader getBeanClassLoader();
void setTempClassLoader(ClassLoader tempClassLoader);
ClassLoader getTempClassLoader();
// 是否需要缓存Bean Metadata(热加载开关)
void setCacheBeanMetadata(boolean cacheBeanMetadata);
boolean isCacheBeanMetadata();
// 定义用于解析BeanDefinition的表达式解析器
void setBeanExpressionResolver(BeanExpressionResolver resolver);
BeanExpressionResolver getBeanExpressionResolver();
// 类型转换服务
void setConversionService(ConversionService conversionService);
ConversionService getConversionService();
// 属性编辑器
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
// BeanFactory用来转换bean属性值或者参数值的自定义转换器
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor>
propertyEditorClass);
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
// 类型转换器
void setTypeConverter(TypeConverter typeConverter);
TypeConverter getTypeConverter();
void addEmbeddedValueResolver(StringValueResolver valueResolver);
String resolveEmbeddedValue(String value);
// Bean处理器
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
int getBeanPostProcessorCount();
// 作用域定义
void registerScope(String scopeName, Scope scope);
String[] getRegisteredScopeNames();
Scope getRegisteredScope(String scopeName);
// 访问权限控制
AccessControlContext getAccessControlContext();
// 合并其他ConfigurableBeanFactory的配置,包括上面说到的BeanPostProcessor,作用域等
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
// Bean别名处理
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
void resolveAliases(StringValueResolver valueResolver);
// Bean定义处理
BeanDefinition getMergedBeanDefinition(String beanName)
throws NoSuchBeanDefinitionException;
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
// Bean创建状态控制.在解决循环依赖时有使用
void setCurrentlyInCreation(String beanName, boolean inCreation);
boolean isCurrentlyInCreation(String beanName);
// 处理Bean依赖
void registerDependentBean(String beanName, String dependentBeanName);
String[] getDependentBeans(String beanName);
String[] getDependenciesForBean(String beanName);
// 销毁Bean
void destroyBean(String beanName, Object beanInstance);
void destroyScopedBean(String beanName);
void destroySingletons();
}
ConfigurableBeanFactory接口,提供了配置BeanFactory的能力以及作为BeanFactory的界面来使用。值得注意的是,setParentBeanFactory()方法只能设置一次,不能改变,而setBeanClassLoader()方法,也只能应用于BeanDefinition。
Bean实例有两个作用域:singleton 单例和 prototype 原型,应用于方法registerScope()。值得注意的是,除了容器内Bean实例的多寡之外,它们的生命周期也是不同的。不管何种作用域,IoC容器都会调用所有Bean实例的初始化回调方法,而对prototype作用域的Bean实例而言,任何生命周期内的析构回调方法都将不被调用。也就是说,Spring不对一个prototype bean的整个生命周期负责,容器在初始化、配置、修饰或者是装配完一个prototype实例,并将它交给客户端后,就对该prototype实例不闻不问了。清理prototype作用域的Bean实例并释放任何prototype实例所持有的昂贵资源,都将是客户端代码的职责。
其抽象子类 AbstractBeanFactory,不仅提供了ConfigurableBeanFactory SPI ③的全部功能,并且继承了DefaultSingletonBeanRegistry,提供单例缓存和顺序执行Bean释放的能力。
AbstractBeanFactory内部维护的一些成员变量:
1)cacheBeanMetadata:是否缓存bean元数据,默认为true;
2)hasInstantiationAwareBeanPostProcessors:表示是否已经注册了InstantiationAwareBeanPostProcessor,默认为false;
3)hasDestructionAwareBeanPostProcessors:表示是否已经注册了DestructionAwareBeanPostProcessor,默认为false;
4)beanPostProcessors:要在createBean中应用的beanPostProcessors集;
5)scopes:容器中bean实例作用域的映射集;
6)mergedBeanDefinitions:beanName和RootBeanDefinition的映射集;
7)alreadyCreated:已经创建过至少一次的beanName;
8)prototypesCurrentlyInCreation:当前正在创建的beanName,使用ThreadLocal;
- ConfigurableListableBeanFactory(配置清单IoC)
public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
// 设置忽略的依赖关系,注册找到的特殊依赖
void ignoreDependencyType(Class<?> type);
void ignoreDependencyInterface(Class<?> ifc);
void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException;
// 获取bean定义 (可以访问属性值跟构造方法的参数值)
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 迭代BeanNames
Iterator<String> getBeanNamesIterator();
// 清除元数据缓存
void clearMetadataCache();
// 锁定配置信息.在调用refresh时会使用到.
void freezeConfiguration();
boolean isConfigurationFrozen();
// 预加载不是懒加载的单例.用于解决循环依赖问题
void preInstantiateSingletons() throws BeansException;
}
扩展至ConfigurableBeanFactory接口。该扩展接口除了添加访问BeanDefinition和配置信息外,还提供了预实例化单例的能力。
其实现类 DefaultListableBeanFactory是基础IoC默认的完整实现,可以作为独立的bean工厂使用,也可以作为定制bean工厂的超类。
DefaultListableBeanFactory内部维护的一些成员变量:
1)allowBeanDefinitionOverriding:是否允许同名不同BeanDefinition再次进行注册;
2)allowEagerClassLoading:是否允许eager类(相对于lazy)加载,甚至延迟初始化bean的加载;
3)configurationFrozen:是否可以为所有bean 缓存BeanDefinition元数据;
4)resolvableDependencies:依赖类型和其对应的自动绑定值的映射集;
5)beanDefinitionMap:BeanDefinition对象的映射集;
6)allBeanNamesByType:非单例bean名称的映射集;
7)singletonBeanNamesByType:单例bean名称的映射集;
8)beanDefinitionNames:BeanDefinition名称列表,以注册顺序;
二、ApplicationContext(应用上下文)
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory,
HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher,
ResourcePatternResolver {
// 返回此应用上下文的唯一ID
String getId();
// 返回此上下文所属的部署应用程序的名称
String getApplicationName();
// 返回此上下文的友好名称
String getDisplayName();
// 首次加载此上下文时返回时间戳
long getStartupDate();
// 返回父上下文,如果为null,即上下文层次结构的根
ApplicationContext getParent();
// 公开AutowireCapableBeanFactory
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
作为应用上下文,在它的设计中,一方面,可以看到它继承了基础IoC体系中的 AutowireCapableBeanFactory、HierarchicalBeanFactory 接口,具备了基础IoC容器的基本能力,另一方面,通过继承 MessageSource、ApplicationEventPublisher、ResourceLoader 等接口,它被赋予了许多高级IoC的特性,而且为了在Web环境使用它,还设计了 WebApplicationContext 接口,通过继承ThemeSource接口来添加附件的功能。所以,一般建议使用 ApplicationContext 作为IoC容器的基本形式。
应用上下文系列容器与其它接口、抽象类、实现类之间的关系:
- WebApplicationContext(Web上下文)
public interface WebApplicationContext extends ApplicationContext {
// 作用域
String SCOPE_REQUEST = "request";
String SCOPE_SESSION = "session";
String SCOPE_GLOBAL_SESSION = "globalSession";
String SCOPE_APPLICATION = "application";
String SERVLET_CONTEXT_BEAN_NAME = "servletContext";
// environment bean
String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";
String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";
// 绑定的Context属性名
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
// 获取标准Servlet API
ServletContext getServletContext();
}
除提供标准的应用上下文生命周期的功能以外,WebApplicationContext通常被用作Web应用程序的上下文界面来使用。 每个应用程序都有单个根上下文,而应用程序中的每个servlet(包括MVC框架中的调度程序servlet)都有自己的子上下文。
GenericWebApplicationContext是其通用实现,适用于Web环境,但不适用于web.xml中的声明式安装,而是设计用于编程式设置。
XmlWebApplicationContext是最常见的WebApplicationContext。
- ConfigurableApplicationContext(可配置上下文)
public interface ConfigurableApplicationContext extends ApplicationContext,
Lifecycle, Closeable {
// 多个上下文配置路径之间的分隔符
String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
// Bean工厂中的属性名
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
String ENVIRONMENT_BEAN_NAME = "environment";
String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
void setId(String id);
void setParent(ApplicationContext parent);
ConfigurableEnvironment getEnvironment();
void setEnvironment(ConfigurableEnvironment environment);
// 添加一个新的BeanFactoryPostProcessor
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor);
// 添加上下文监听器
void addApplicationListener(ApplicationListener<?> listener);
// 刷新上下文
void refresh() throws BeansException, IllegalStateException;
// 注册一个关闭钩子 ShutdownHook
void registerShutdownHook();
// 关闭上下文
void close();
// 是否活跃,即是否已刷新至少一次并尚未关闭
boolean isActive();
//
ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}
扩展了ApplicationContext界面中的应用上下文SPI,通常配置和生命周期相关方法被封装在这里,以避免使它们对ApplicationContext客户端代码显而易见。
AbstractApplicationContext是其抽象实现,其refresh()方法只能被调用一次。典型的用法是通过BeanDefinitionRegistry接口注册各种bean定义,然后调用AbstractApplicationContext#refresh()方法来初始化具有应用上下文语义的Bean(如ApplicationContextAware、BeanFactoryPostProcessors等)。
GenericApplicationContext是其通用实现,也是通用的ApplicationContext实现。
三、其它相关的一些特性
- FactoryBean:
public interface FactoryBean<T> {
// 返回Bean实例,如果是单实例,则该实例会放到IoC容器中的单实例缓存池中
T getObject() throws Exception;
// 返回Bean类型
Class<?> getObjectType();
// Bean实例的作用域是否是singleton
boolean isSingleton();
}
其实这很好理解,一个是Bean工厂,是IoC容器;一个是工厂Bean,用来生产对象或修饰对象生成的一类Bean。相对应的,一个是IoC设计模式,Inversion of Control 控制反转或者说是依赖注入,就是把组件之间的依赖关系从代码中移出去,通过可读的文本配置来进行浏览和管理,降低维护成本提高管理水平;一个是抽象工厂模式和修饰模式,它提供了一种封装机制,比如封装了Proxy、RMI、JNDI,在合适的场合将它们修饰进生产出来的对象中,所以,它返回的对象并不是指定一个类的实例。
你可以通过转义符“&”来获得FactoryBean本身,而非这个FactoryBean产生出来的对象 ②。
Spring 自身提供了70多个FactoryBean的实现,并且从Spring 3.0版本开始,FactoryBean开始支持泛型,接口声明改为FactoryBean<T>的形式。
- ObjectFactory:
public interface ObjectFactory<T> {
// 获取Bean实例
T getObject() throws BeansException;
}
简单来说,对象工厂,用来生产Bean实例的,它只有一个方法 getObject()
ObjectFactory接口和FactoryBean接口有些类似,但实际上,FactoryBean的实现是作为一个SPI来在BeanFactory内部使用的,它相当于是BeanFactory#getBean()的代理。而ObjectFactory实现是被用来注入到其它Bean中作为API来使用的,这在Sprin IoC核心的源码中随处可见,通过ObjectFactory实现来取得我们想要的Bean实例。
- BeanWrapper:
public interface BeanWrapper extends ConfigurablePropertyAccessor {
// 返回由此对象包装的bean实例
Object getWrappedInstance();
// 返回包装的Bean实例的类型
Class<?> getWrappedClass();
// 获取包装对象的属性描述符
PropertyDescriptor[] getPropertyDescriptors();
PropertyDescriptor getPropertyDescriptor(String propertyName)
throws InvalidPropertyException;
boolean isAutoGrowNestedPaths();
void setAutoGrowNestedPaths(boolean autoGrowNestedPaths);
void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
int getAutoGrowCollectionLimit();
}
BeanWrapper接口,持有创建出来的Bean对象,封装持有的对象的行为。但事实上它并不简单,由于其继承了属性访问接口、属性编辑注册接口、类型转换接口,不仅可以单个或批量的设置以及访问被包装对象的属性值,多种不同类型的属性值类型转换,还支持可以无限深度的设置嵌套属性 ④。
通常情况下,不建议在应用程序中直接使用BeanWrapper,而是采用DataBinder或BeanFactory。因为大部分情况下,BeanWrapper是在IoC容器内部进行使用,所有Bean实例的属性设置也都是交给它来实现,以统一的方式来访问Bean属性。
- PropertyAccessor接口:属性访问器,定义了各种访问bean属性的方法;
- PropertyEditorRegistry接口:属性编辑器,提供将配置文件中字面值转换为具体属性类型的对象的能力;
- TypeConverter接口:类型转换器,通常与PropertyEditorRegistry接口一起实现;
- DataBinder接口:数据绑定,将属性值设置到目标对象上的绑定,支持验证和绑定结果分析;
- BeanWrapperImpl实现类:对BeanWrapper接口的默认实现,内部会对被包装对象的Class进行内省分析,其PropertyDescriptor结果将缓存在CachedIntrospectionResults对象中。
- BeanDefinition:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
//------------- Bean角色 -------------
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
String getParentName();
void setParentName(String parentName);
String getBeanClassName();
void setBeanClassName(String beanClassName);
String getFactoryBeanName();
void setFactoryBeanName(String factoryBeanName);
String getFactoryMethodName();
void setFactoryMethodName(String factoryMethodName);
String getScope();
void setScope(String scope);
boolean isLazyInit();
void setLazyInit(boolean lazyInit);
String[] getDependsOn();
void setDependsOn(String... dependsOn);
boolean isAutowireCandidate();
void setAutowireCandidate(boolean autowireCandidate);
boolean isPrimary();
void setPrimary(boolean primary);
ConstructorArgumentValues getConstructorArgumentValues();
MutablePropertyValues getPropertyValues();
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
int getRole();
String getDescription();
String getResourceDescription();
BeanDefinition getOriginatingBeanDefinition();
}
BeanDefinition接口表示Bean定义,IoC容器是用来解构和管理对象依赖关系的,对IoC容器来说,BeanDefinition就是对依赖反转模式中管理的对象依赖关系的数据抽象,也是IoC容器用来实现依赖反转功能的核心数据结构,依赖反转功能都是围绕着对这个BeanDefinition的处理来完成。
BeanDefinition类图如下:
- AttributeAccessor接口:提供访问name/value属性的能力;
- BeanMetadataElement接口:提供访问source(配置源)的能力;
- AnnotatedBeanDefinition接口:提供管理BeanDefinition注解的数据的能力;
- AbstractBeanDefinition抽象类:提供BeanDefinition属性,公共判断,重写了equals、hashCode、toString方法。
AbstractBeanDefinition内部字段:
// bean原始类型 private volatile Object beanClass; // bena的作用域 private String scope = ""; // 是否单例 private boolean singleton = true; // 是否原型 private boolean prototype = false; // 是否抽象定义 private boolean abstractFlag = false; // 是否预实例化 private boolean lazyInit = false; // 自动装配模式 private int autowireMode = 0; // 是否依赖检查 private int dependencyCheck = 0; // 依赖的bean private String[] dependsOn; // 装配候选人 private boolean autowireCandidate = true; // 单值依赖时的优先权 private boolean primary = false; // 非公开访问允许 private boolean nonPublicAccessAllowed = true; // 宽松的构造方法 private boolean lenientConstructorResolution = true; // 构造函数参数列表 private ConstructorArgumentValues constructorArgumentValues; // 多个属性值 private MutablePropertyValues propertyValues; // 方法覆盖 private MethodOverrides methodOverrides = new MethodOverrides(); // FactoryBean名称 private String factoryBeanName; // FactoryBean方法名 private String factoryMethodName; // <init-method>方法名 private String initMethodName; // <destroy>方法名 private String destroyMethodName; // init方法名 private boolean enforceInitMethod = true; // destroy方法名 private boolean enforceDestroyMethod = true; // 合成标识 private boolean synthetic = false; // 角色 private int role = 0; // 描述信息 private String description; // 资源位置 private Resource resource; // 装配后续的限定词 private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<String, AutowireCandidateQualifier>(0);
- RootBeanDefinition实现类:表示运行时统一的(合并)BeanDefinition视图;
- ChildBeanDefinition实现类:表示子BeanDefinition具有父BeanDefinition的固有依赖;
- GenericBeanDefinition实现类:Spring 2.5以后,该实现是标准Bean定义目的的一站式服务,允许动态的定义父子依赖。一般来说,是以编程方式注册用户可见Bean定义的首选,是ChildBeanDefinition和RootBeanDefinition更好的替代品。
另外还有一个BeanDefinitionHolder类,不在上面的类图里,但却是BeanDefinition的封装类。该实例持有BeanDefinition、Bean名字以及别名等信息,用它来临时保存BeanDefinition来完成IoC容器注册。
- BeanDefinitionRegistry
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是否已注册
boolean containsBeanDefinition(String beanName);
// 获取注册表中所有BeanDefinition实例的beanName
String[] getBeanDefinitionNames();
// 获取注册表中BeanDefinition实例的数量
int getBeanDefinitionCount();
// beanName是否被占用
boolean isBeanNameInUse(String beanName);
}
BeanDefinitionRegistry接口主要作用是向注册表中注册BeanDefinition实例,以完成Bean注册的过程。实现类一般通过一个HashMap类型的成员变量beanDefinitionMap来持有载入的BeanDefinition。
- AliasRegistry接口:提供别名注册的能力,实现类通常以一个HashMap类型的成员变量aliasMap来持有载入的Alias;
- SingletonBeanRegistry接口:提供单例对象注册的能力;
- DefaultSingletonBeanRegistry实现类:单例对象的通用注册表。它作为SingletonBeanRegistry接口的默认实现,其内部维护了四个集合(Map和Set)作为单例Bean的注册表,两个Map维护Bean实例的依赖关系,还支持登记DisposableBean实例,以执行适当的关闭顺序。
DefaultSingletonBeanRegistry内部维护的一些成员变量:
1)NULL_OBJECT:表示空值单例对象,用作并发映射的标记值;
2)singletonObjects:单例对象缓存池
bean name --> bean instance
3)singletonFactories:单例ObjectFactory的缓存池
bean name --> ObjectFactory
4)earlySingletonObjects:预先暴露的单例对象缓存池
bean name --> ObjectFactory
5)registeredSingletons:单例对象的注册表;
6)singletonsCurrentlyInCreation:当前正在创建的beanName,使用ConcurrentHashMap;
7)inCreationCheckExclusions:当前在初始化检查中被排除的beanName,使用ConcurrentHashMap;
8)suppressedExceptions:抑制异常的白名单,用于关联相关原因;
9)singletonsCurrentlyInDestruction:标识当前BeanFactory是否在destroy;
10)disposableBeans:登记的DisposableBean实例,以执行适当的关闭顺序
bean name --> disposable instance
11)containedBeanMap:两个Bean之间的依赖(包含)关系的映射集;
bean name --> contains bean names Set
12)dependentBeanMap:bean之间依赖的映射集;
bean name --> dependent bean names Set
13)dependenciesForBeanMap:bean之间依赖的映射集;
bean name --> bean's dependencies bean names Set
- FactoryBeanRegistrySuppourt抽象类:在DefaultSingletonBeanRegistry的基础上增加了对FactoryBeans创建的单例对象的缓存池。
DefaultSingletonBeanRegistry内部维护的一些成员变量:
1)factoryBeanObjectCache:FactoryBeans创建的单例对象缓存池
FactoryBean name --> object
- BeanDefinitionReader
public interface BeanDefinitionReader {
// 获取BeanDefinitionRegistry
BeanDefinitionRegistry getRegistry();
// 获取Bean名称生成器
BeanNameGenerator getBeanNameGenerator();
ResourceLoader getResourceLoader();
ClassLoader getBeanClassLoader();
//载入BeanDefinition
int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;
int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;
int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;
int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}
简单来说,就是BeanDefinition读取器的统一界面,从给定的资源或字符串位置参数加载或注册BeanDefinition。具体的实现类特定于它们定义的格式。
另外还有两个类值得注意:
— AnnotatedBeanDefinitionReader,用于编程方式注册的Bean定义;
— BeanDefinitionDocumentReader,用于解析包含BeanDefinition的DOM文档,组合 XmlBeanDefinitionReader和BeanDefinitionParserDelegate来实现。
- Resource
public interface Resource extends InputStreamSource {
// 是否存在
boolean exists();
// 是否可读
boolean isReadable();
// 是否打开
boolean isOpen();
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
// 资源的长度
long contentLength() throws IOException;
// 获取文件名
String getFilename();
// 返回当前Resource表示的底层资源的最后修改时间
long lastModified() throws IOException;
// 返回此资源的描述信息,用于在使用资源时输出错误
String getDescription();
// 创建相对于此底层资源的资源
Resource createRelative(String relativePath) throws IOException;
}
JDK操作底层资源的接口基本上都是 java.net.URL、java.io.File 等,这就增加了系统的复杂性,因此Spring抽象出一个Resource接口 ,它封装了对具体资源的I/O操作,提供了统一的访问外部资源的策略界面。
- ResourceLoader
public interface ResourceLoader {
// 从类路径加载的伪URL前缀: "classpath:"
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
Resource getResource(String location);
ClassLoader getClassLoader();
}
同样是加载资源的策略界面,该接口主要的作用是判断传入的Resource相关字符串,根据location参数返回不同的Resource。 所以,它可以看做是Resource的工厂类。
- DefaultResourceLoader实现类:是ResourceLoader接口的默认实现,通常内部由ResourceEditor使用。
DefaultResourceLoader获取Resource时,默认策略:
- 首先判断指定的location是否含有“/”前缀,有则返回ClassPathContextResource;
- 然后判断指定的location是否含有“classpath:”前缀,有则把location去掉“classpath:”前缀返回对应的ClassPathResource;
- 否则就把它当做一个URL来处理,封装成一个UrlResource返回;
- 如果当做URL处理也失败的话,就把location对应的资源当成是一个ClassPathContextResource返回。 - ResourcePatternResolver接口:提供将位置模式字符解析为Resource对象的能力,是ResourceLoader策略界面的扩展。
locationPattern前缀的,默认策略:
classpath : 用于加载类路径(包括jar包)中的一个且仅一个资源;
classpath* : 用于加载类路径(包括jar包)中的所有匹配的资源,可使用Ant路径模式。
注:
① 本篇幅中的IoC容器,均指的是SpringFramework的IoC系列容器;
② Dereference(间接引用),一个在C/C++中应用的比较多的术语,它表示变量所指向的是所引用对象的本身数据,而不是对象的内存地址。在C++中,“*”是解引用符号,“&”是引用符号;
③ SPI(Service Provider Interface),表示被第三方来实现或扩展的API,它可以用来扩展框架或实现组件以替换功能。
④ 值得注意的是,设置对象属性值时存在一些潜在的约定规则,比如:
name | 指向属性name,与getName() 、isName() 和 setName()相对应。 |
account.name | 指向属性account的嵌套属性name,与之对应的是getAccount().setName()和getAccount().getName() |
account[2] | 指向索引属性account的第三个元素,索引属性可能是一个数组(array)、列表(list)或其它天然有序的容器。 |
account[COMPANYNAME] | 指向一个Map实体account中以COMPANYNAME作为键值(key)所对应的值 |
参考:
- 《Spring 技术内幕》;
- Spring 3.2 API:http://docs.spring.io/spring/docs/3.2.x/javadoc-api/index.html