参考资源
BeanFactory接口体系源码分析
下图为spring源码中BeanFactory接口体系结构
spring的BeanFactory接口体系结构中,每个结构实现特定功能,这个满足设计模式的原则:接口隔离原则
下面我们来逐个分析每个接口的源码
BeanFactory接口
/*
1.这个根接口可访问spring bean容器,具备访问容器中bean的基本功能,
像ListableBeanFactory和ConfigurableBeanFactory这些接口会有其他专门的功能
2.该接口由包含一些bean definitions的对象实现,这些bean definitions是由一个string类型的name唯一标识的。根据bean definition,该工厂要么返回容器中的一个对象所对应的独立实例(原型设计模式),或者是一个单例对象。返回哪一种实例由工厂配置决定。单例方法比较常用。
3.BeanFactory是应用程序组件的中心注册处,并集中配置应用程序组件(例如,单个对象不再需要读取属性文件)。
4.通过调用setter函数或者是构造函数来配置应用对象的方式更好,spring的依赖注入功能由BeanFactory和它的子接口实现
5.BeanFactory一般加载bean definitions,这些definitions一般存储在配置文件中(比如xml文件中),然后使用org.springframework.beans包来配置beans。definitions的存储形式是不限定的,可以采用:LDAP、XML或者是配置文件等形式。
6.和ListableBeanFactory接口中的方法相比,HierarchicalBeanFactory接口中的方法将会检查父工厂。如果在所有的工厂实例中找不到所要得bean,那么将会访问直系父工厂。但是,在子工厂实例中的bean将会覆盖父工厂中相同名称的实例。
7.BeanFactory需要管理bean的生命周期,比如初始化时需要按顺序实现如下接口:
1]. BeanNameAware's {@code setBeanName}
2]. BeanClassLoaderAware's {@code setBeanClassLoader}
3]. BeanFactoryAware's {@code setBeanFactory}
4]. ResourceLoaderAware's {@code setResourceLoader}仅对application context有效
5]. ApplicationEventPublisherAware's {@code setApplicationEventPublisher}仅对application context有效
6]. MessageSourceAware's {@code setMessageSource}仅对application context有效
7]. ApplicationContextAware's {@code setApplicationContext}仅对application context有效
8]. ServletContextAware's {@code setServletContext}仅对application context有效
9]. {@code postProcessBeforeInitialization} methods of BeanPostProcessors
10]. InitializingBean's {@code afterPropertiesSet}
11]. a custom init-method definition xml中配置的init-method
12. {@code postProcessAfterInitialization} methods of BeanPostProcessors
还有关闭容器的接口:
1]. DisposableBean's {@code destroy}
2]. a custom destroy-method definition xml配置中的destroy-method
*/
public interface BeanFactory {
//用来区分是获取FactoryBean还是FactoryBean的createBean创建的实例.如果&开始则获取FactoryBean;否则获取createBean创建的实例.
String FACTORY_BEAN_PREFIX = "&";
//根据name获得bean实例(可以为单例实例或者是原型实例)
//Spring BeanFactory可以看做是单例模式和原型模式的替代品,即Spring BeanFactory可以生成满足单例模式或是原型模式的实例
//将别名转换回相应的规范bean名称,即可以使用别名查找
//如果在本工厂中没有找到bean则需要在父工厂中寻找
Object getBean(String name) throws BeansException;
/**
* Return an instance (possibly shared or independent) of the given bean name.
* <p>Behaves the same as getBean(String), but provides a measure of type safety by
* throwing a Spring BeansException if the bean is not of the required type.
* This means that ClassCastException can't be thrown on casting the result correctly,
* as can happen with <code>getBean(String)</code>.
* @param name the name of the bean to return
* @param requiredType type the bean must match. Can be an interface or superclass
* of the actual class, or <code>null</code> for any match. For example, if the value
* is <code>Object.class</code>, this method will succeed whatever the class of the
* returned instance.
* @return an instance of the bean (never <code>null</code>)
* @throws BeanNotOfRequiredTypeException if the bean is not of the required type
* @throws NoSuchBeanDefinitionException if there's no such bean definition
* @throws BeansException if the bean could not be created
*/
//根据name获得bean实例(可以为单例实例或者是原型实例)
//功能和getBean(String name)一样,但是本方法会提供一种类型检测策略,当获得的bean不是所给的类型requiredType时会抛出异常BeansException
//这意味着不能在转换结果时抛出ClassCastException,但是在getBean(String)可以
Object getBean(String name, Class requiredType) throws BeansException;
/**
* Does this bean factory contain a bean definition with the given name?
* <p>Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @return whether a bean with the given name is defined
*/
//根据所给的name判断是否有对应的bean definition
//如果在本工厂实例中找不到对应的bean,那么就会去父工厂中寻找
//陷阱出现:这边不管类是否抽象类,懒加载,是否在容器范围内,只要符合都返回true,所以这边true,不一定能从getBean获取实例
boolean containsBean(String name);
/**
* Is this bean a singleton? That is, will <code>getBean</code> always return the same object?
* <p>Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @return is this bean a singleton
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @see #getBean
*/
//判断获得的bean是否为单例实例,如果是,那么每次调用getBean返回的是同一个对象
//
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
//根据name,获得对应bean的类型信息
Class getType(String name) throws NoSuchBeanDefinitionException;
//根据name,返回对应的bean的别名
String[] getAliases(String name) throws NoSuchBeanDefinitionException;
}
AutowireCapableBeanFactory接口
在BeanFactory基础上实现对已存在实例的管理.
可以使用这个接口集成其它框架,捆绑并填充并不由Spring管理生命周期并已存在的实例.像集成WebWork的Actions 和Tapestry Page就很实用.
一般应用开发者不会使用这个接口,所以像ApplicationContext这样的外观实现类不会实现这个接口,如果真手痒痒可以通过ApplicationContext的getAutowireCapableBeanFactory接口获取.
(由于在编程中不怎么使用,所以就先不详细分析了)
HierarchicalBeanFactory
提供父容器的访问功能,至于父容器的设置,需要找ConfigurableBeanFactory的setParentBeanFactory(接口把设置跟获取给拆开了!).
public interface HierarchicalBeanFactory extends BeanFactory {
//返回父工厂
BeanFactory getParentBeanFactory();
//判断在本地工厂中是否包含name指定的bean
boolean containsLocalBean(String name);
}
ListableBeanFactory接口
获取bean时,Spring 鼓励使用这个接口定义的api. 还有个BeanFactory方便使用.其他的4个接口都是不鼓励使用的.
/**
*这个接口的实现实例可以枚举工厂中的所有bean实例,而不是由用户一个个通过name来查找。那些能够预先加载beans(比如DOM-based XML factories)将会实现该接口。
* 如果同时实现了HierarchicalBeanFactory,返回值不会考虑父类BeanFactory,只考虑当前factory定义的类.当然也可以使用BeanFactoryUtils辅助类来查找祖先工厂中的类.
* 这个接口中的所有方法只会考虑本factory的bean definitions,会忽略掉由ConfigurableBeanFactory的registerSingleton方法注册到本工厂中的单例,(但是getBeanNamesOfType和getBeansOfType这两个方法是例外,一样会考虑手动注册的单例),当然BeanFactory的getBean一样可以透明访问这些特殊bean.当然在典型情况下,所有的bean都是由external bean定义,所以应用不需要顾虑这些差别.
public interface ListableBeanFactory extends BeanFactory {
//检查在本factory中是否包含有指定beanName的bean definition
//会忽略手动注册进本factory的bean,只会考虑通过bean definition进入工厂的bean
boolean containsBeanDefinition(String beanName);
//获得本factory中定义的bean的数量
//会忽略手动注册进本factory的bean,只会考虑通过bean definition进入工厂的bean
int getBeanDefinitionCount();
//获得本factory中定义的所有bean的名字
//会忽略手动注册进本factory的bean,只会考虑通过bean definition进入工厂的bean
String[] getBeanDefinitionNames();
//根据bean definition,匹配所给类型的bean的名称,如果bean是所给类type的子类实例,那么名字也会被返回
String[] getBeanDefinitionNames(Class type);
//根据bean definition,或者是工厂实例调用getObjectType的返回值,匹配所给类型的bean的名称,如果bean是所给类type的子类实例,那么名字也会被返回
String[] getBeanNamesForType(Class type);
String[] getBeanNamesForType(Class type, boolean includePrototypes, boolean includeFactoryBeans);
Map getBeansOfType(Class type) throws BeansException;
Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans)
throws BeansException;
}
ConfigurableBeanFactory
大部分的工厂类会实现该接口,实现该接口的类将具备配置工厂的能力。
定义BeanFactory的配置.
这边定义了太多太多的api,比如类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系,合并其他ConfigurableBeanFactory,bean如何销毁.
定义了两个作用域: 单例和原型.可以通过registerScope来添加.
SCOPE_SINGLETON,SCOPE_PROTOTYPE
这边定义了好多好多的api,所以我们这边只讲业务,具体的api看文末的附录吧:
a, 父容器设置.而且一旦设置了就不让修改
b, 类加载器设置与获取.默认使用当前线程中的类加载器
c, 为了类型匹配,搞个临时类加载器.好在一般情况为null,使用上面定义的标准加载器
d, 是否需要缓存bean metadata,比如bean difinition 和 解析好的classes.默认开启缓存
e, 定义用于解析bean definition的表达式解析器
f, 类型转化器
g, 属性编辑器
h, BeanFactory用来转换bean属性值或者参数值的自定义转换器
i,string值解析器(想起mvc中的ArgumentResolver了)
j,大boss BeanPostProcessor用于增强bean初始化功能
k,作用域定义
l,访问权限控制
m, 合并其他ConfigurableBeanFactory的配置,包括上面说到的BeanPostProcessor,作用域等
n, bean定义处理
o, bean创建状态控制.在解决循环依赖时有使用
p, 处理bean依赖问题
q, bean生命周期管理-- 销毁bean
ConfigurableListableBeanFactory
提供bean definition的解析,修改bean definition,注册功能,再对单例来个预加载(解决循环依赖问题).
貌似我们一般开发就会直接定义这么个接口了事.而不是像Spring这样先根据使用情况细分那么多,到这边再合并
public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
/**
在自动分装时,忽略依赖的类型
*/
void ignoreDependencyType(Class type);
/**
在自动分装时,忽略依赖的接口
*/
void ignoreDependencyInterface(Class ifc);
/**
* Return the registered BeanDefinition for the given bean, allowing access
* to its property values and constructor argument value (which can be
* modified during bean factory post-processing).
获取bean定义 (可以访问属性值跟构造方法的参数值)
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
//锁定配置信息.在调用refresh时会使用到.
void freezeConfiguration();
boolean isConfigurationFrozen();
/**
保证所有的懒加载的单例实例,以及FactoryBean实例被加载,如果需要的话,在工厂启动最后调用该方法
* Ensure that all non-lazy-init singletons are instantiated, also considering
* FactoryBeans. Typically invoked at the end of factory setup, if desired.
* <p>As this is a startup method, it should destroy already created singletons
* if it fails, to avoid dangling resources. In other words, after invocation
* of that method, either all or no singletons at all should be instantiated.
* @throws BeansException if one of the singleton beans could not be created
*/
void preInstantiateSingletons() throws BeansException;
}
附录--ConfigureableBeanFactory中定义的api:
a, 父容器设置.而且一旦设置了就不让修改
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
b, 类加载器设置与获取.默认使用当前线程中的类加载器
void setBeanClassLoader(ClassLoader beanClassLoader);
ClassLoader getBeanClassLoader();
c, 为了类型匹配,搞个临时类加载器.好在一般情况为null,使用上面定义的标准加载器
void setTempClassLoader(ClassLoader tempClassLoader);
ClassLoader getTempClassLoader();
d, 是否需要缓存bean metadata,比如bean difinition 和 解析好的classes.默认开启缓存
void setCacheBeanMetadata(boolean cacheBeanMetadata);
boolean isCacheBeanMetadata();
e, 定义用于解析bean definition的表达式解析器
void setBeanExpressionResolver(BeanExpressionResolver resolver);
BeanExpressionResolver getBeanExpressionResolver();
f, 类型转化器
void setConversionService(ConversionService conversionService);
ConversionService getConversionService();
g, 属性编辑器
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
h, BeanFactory用来转换bean属性值或者参数值的自定义转换器
void setTypeConverter(TypeConverter typeConverter);
TypeConverter getTypeConverter();
i,string值解析器(想起mvc中的ArgumentResolver了)
void addEmbeddedValueResolver(StringValueResolver valueResolver);
String resolveEmbeddedValue(String value);
j,大boss BeanPostProcessor用于增强bean初始化功能
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
int getBeanPostProcessorCount();
k,作用域定义
void registerScope(String scopeName, Scope scope);
String[] getRegisteredScopeNames();
Scope getRegisteredScope(String scopeName);
l,访问权限控制
AccessControlContext getAccessControlContext();
m, 合并其他ConfigurableBeanFactory的配置,包括上面说到的BeanPostProcessor,作用域等
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
n, bean定义处理
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException; // 注册别名
void resolveAliases(StringValueResolver valueResolver);
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; // 合并bean定义,包括父容器的
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException; // 是否是FactoryBean类型
o, bean创建状态控制.在解决循环依赖时有使用
void setCurrentlyInCreation(String beanName, boolean inCreation);
boolean isCurrentlyInCreation(String beanName);
p, 处理bean依赖问题
void registerDependentBean(String beanName, String dependentBeanName);
String[] getDependentBeans(String beanName);
String[] getDependenciesForBean(String beanName);
q, bean生命周期管理-- 销毁bean
void destroyBean(String beanName, Object beanInstance);
void destroyScopedBean(String beanName);
void destroySingletons();