Spring Bean 工厂是Spring框架提供的一种机制,用于创建和管理对象(或称为Bean)。它是Spring框架的核心部分,提供了一种灵活、可配置的方式来管理对象的生命周期和依赖关系。
下面展示了整个 Bean 工厂的常见接口和类以及功能(其中 XmlBeanFactory 已经被弃用):
1、不同的接口展现了不同的能力,是对子类能力的抽象;
2、 抽象类构建通用方法的实现,是通用核心方法的具体实现;
3、 具体类完成特定功能的实现,是特定功能的具体实现;
public interface BeanFactory {
// 这个变量在获取一个 FactoryBean 的时候使用
// 定义 FactoryBean 时的前缀
String FACTORY_BEAN_PREFIX = "&";
// 工厂的核心方法,提供了多种获取单个实例bean的能力
// 有不同的获取方式:别名直接获取、别名+参数,根据对应构造获取、类型注入
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
// 返回对应的 ObjectProvider,这是一种可以延迟获取 bean 实例的模式
// 比如基于 ObjectProvider#getIfUnique 方法获取实例(获取容器中的对象)
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
// 判断是否包含指定 name 的 bean Definition 或 单例
// 此处返回 true 并不意味着 getBean 可以返回对应的实例
boolean containsBean(String name);
// 判断 name 对应的 bean 是否是单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
// 判断 name 对应的 bean 是否是原型(prototype)
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
// 判断指定 name 的bean是否匹配对应的类型
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
// 获取 name 对应的 bean 的类型
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
@Nullable
Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
// 返回指定 name 的所有别名
String[] getAliases(String name);
}
在 Spring4.3 之前,我们的bean如果需要使用特定构造器进行构造时必须使用@Autowired注解:
@Service
public class UserService {
private UserDao userDao;
@Autowired
public UserService(UserDao userDao) {
this.userDao = userDao;
}
}
在 Spring4.3 之后,如果没有其他构造器(有无参构造默认会使用无参构造,当然如果无参也没有,还有多个有参),会隐式为其注入:
@Service
public class UserService {
UserDao userDao;
public UserService(UserDao userDao) {
this.userDao = userDao;
}
}
但是当容器中没有 UserDao 这个 Bean 的时候,就会报以下异常:
此时 ObjectProvider
就提供了它的作用了:
@Service
public class UserService {
UserDao userDao;
public UserService(ObjectProvider<UserDao> objectProvider) {
// 如果容器中存在就返回,不存在返回null
this.userDao = objectProvider.getIfUnique();
}
}
这样注入的好处很明显,就是如果容器中不存在 UserDao 或者存在多个 UserDao 时,可以从容处理。
ObjectProvider 接口如下,他继承自 ObjectFactory,这个接口后边也会常用:
public interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T> {
T getObject(Object... args) throws BeansException;
// 处理判断有可用的bean的时候我们怎么做,可以重写
T getIfAvailable() throws BeansException;
default T getIfAvailable(Supplier<T> defaultSupplier) throws BeansException {
T dependency = getIfAvailable();
return (dependency != null ? dependency : defaultSupplier.get());
}
default void ifAvailable(Consumer<T> dependencyConsumer) throws BeansException {
T dependency = getIfAvailable();
if (dependency != null) {
dependencyConsumer.accept(dependency);
}
}
// 处理判断只有唯一的bean的时候我们怎么做,可以重写
T getIfUnique() throws BeansException;
default T getIfUnique(Supplier<T> defaultSupplier) throws BeansException {
T dependency = getIfUnique();
return (dependency != null ? dependency : defaultSupplier.get());
}
default void ifUnique(Consumer<T> dependencyConsumer) throws BeansException {
T dependency = getIfUnique();
if (dependency != null) {
dependencyConsumer.accept(dependency);
}
}
// 当匹配多个时,可以迭代处理
@Override
default Iterator<T> iterator() {
return stream().iterator();
}
}
ObjectFactory 作为一个对象工厂函数式接口更是简单:
@FunctionalInterface
public interface ObjectFactory<T> {
/**
* Return an instance (possibly shared or independent)
* of the object managed by this factory.
* @return the resulting instance
* @throws BeansException in case of creation errors
*/
T getObject() throws BeansException;
}
该工厂继承自 BeanFactory,在含有Bean基础功能的基础上,提供了更强的枚举能力。ListableBeanFactory 为后续的实现类提供了更强的枚举能力,这些能力可能不对外公开,但是对于子类操作容器的操作bean十分重要,下面是他提供的方法:
public interface ListableBeanFactory extends BeanFactory {
// 对BeanDefinition的一些细节操作
boolean containsBeanDefinition(String beanName);
int getBeanDefinitionCount();
String[] getBeanDefinitionNames();
// 对 BeanFactory 中获取ObjectProvider方法的拓展
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit);
// 获取指定类型(子类)的bean names
// boolean includeNonSingletons 参数决定是否考虑 singleotn 以外的bean
// boolean allowEagerInit 是否初始化对应FactoryBean,如果false则类型直接匹配对应的FactoryBean
String[] getBeanNamesForType(ResolvableType type);
String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);
String[] getBeanNamesForType(@Nullable Class<?> type);
String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
/**
基本同上,返回的 Map 结构
k:beanName
v:beanInstance
**/
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
// 返回指定注解的beanName数组
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
// 返回指定注解的bean实例集合:beanName -> bean 实例
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
// 获取指定 beanName 上的注解
// 同样涉及 FactoryBean 初始化的问题,由参数 allowFactoryBeanInit 决定
@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
@Nullable
<A extends Annotation> A findAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
throws NoSuchBeanDefinitionException;
<A extends Annotation> Set<A> findAllAnnotationsOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
throws NoSuchBeanDefinitionException;
}
BeanFactory 的子接口:
BeanFactoryUtils
.containsBeanDefinition、getBeanDefinitionCount、getBeanDefinitionNames
这几个方法是完全基于当前 BeanFactory 中的 BeanDefinition 的,换句话说,对于通过 registerSingleton 等方法注册的 bean 实例,它们是不感知的。getBeanNamesForType、getBeansOfType
方法是会感知自行注册 bean 实例的,当然大多数场景的 bean 实例都是基于 BeanDefinition 扫描的。HierarchicalBeanFactory 为 bean 工厂提供了灵活的分层能力,这在 web 工程里由典型的应用,spring 和 springmvc 会建立两个独立的上下文,分层之后各司其职,更易管理。
public interface HierarchicalBeanFactory extends BeanFactory {
// 返回 bean 工厂的父工厂
@Nullable
BeanFactory getParentBeanFactory();
// 此方法忽略祖先上下文定义的bean,只会查询本地工厂
boolean containsLocalBean(String name);
}
测试一手:
@Test
public void testHierarchicalBeanFactory() {
// 创建一个核心工厂
DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
parent.registerSingleton("person1", new Person("张三", 18));
// 创建一个子工厂工厂,独自管理各个层次的内容
DefaultListableBeanFactory child = new DefaultListableBeanFactory();
// 设置父子关联关系
child.setParentBeanFactory(parent);
// 子工厂可以访问父工厂的bean
log.info("{}", child.getBean("person1"));
log.info("{}", child.containsBean("person1"));
// containsLocalBean()方法判断当前工厂是否包含指定的bean,如果是,则返回true,否则返回false
log.info("{}", child.containsLocalBean("person1"));
}
BeanFactory 的 子接口:
getParentBeanFactory
用于获取父 BeanFactoryname
的 bean实例
.这个接口提供了构建和自动装配的能力,主要是赋予子类自动装配的能力,是容器最核心的接口,这个接口定义了 bean 的创建以及装配能力,同时细粒度的控制了 bean 的生命周期。
public interface AutowireCapableBeanFactory extends BeanFactory {
// 表示不进行自动注入,默认情况下都是该状态
// 真正的注入,一般都是基于 @Autowire 等注解驱动
int AUTOWIRE_NO = 0;
// 基于属性 name 的自动注入模式,一般不用
int AUTOWIRE_BY_NAME = 1;
// 基于属性 type 的自动注入模式,@Bean 方式就是这种模式
int AUTOWIRE_BY_TYPE = 2;
// 基于构造方法的自动注入,一般不用
int AUTOWIRE_CONSTRUCTOR = 3;
// 通过此后缀获取原始实例(比如 代理实例的 target)
String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
// 创建实例的典型方法
<T> T createBean(Class<T> beanClass) throws BeansException;
// 自动填充指定 bean 实例属性,本质上是 after-instantiation 和 property post-processing 回调的执行
void autowireBean(Object existingBean) throws BeansException;
// 配置给定 bean 实例,本质是属性填充以及初始化回调的执行
Object configureBean(Object existingBean, String beanName) throws BeansException;
//--------------------------------------------------------------------
// 用于对bean生命周期进行细粒度控制的专门方法
// 主要是三块内容:创建(实例化) 属性填充(装配) 初始化
//--------------------------------------------------------------------
/**
生命周期第一步(创建)
按照指定的装配策略根据class生成一个完整的bean的实例
执行bean的完全初始化,包括所有适用的beanpostprocessors
@param dependencyCheck 是否对对象执行依赖项检查(不适用于自动装配构造函数,因此忽略)
@return 新的bean的实例
**/
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
/**
生命周期第二步(装配)
基于 autowireMode 创建 bean 实例并自动填充
通过应用 after-instantiation 和 property post-processing(例如注解驱动的注入)
来填充给定的bean实例
**/
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
/**
* 基于 autowireMode 自动填充已经存在的 bean 实例
* 已经存在的实例不支持 AUTOWIRE_CONSTRUCTOR
*/
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
/**
* 基于 BeanDefinition 的属性填充已存在的 bean 实例
*/
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
// 初始化前的回调
// 将 BeanPostProcessors 应用到给定的现有bean实例
// 调用它们的postprocessBeforeInitialization方法
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
// 初始化给定的原始 bean,应用工厂回调,如setBeanName和setBeanFactory
// 当然也包括应用所有的bean postprocessors
Object initializeBean(Object existingBean, String beanName) throws BeansException;
// 初始化后置处理
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
// 销毁给定的bean实例
// 使用DisposableBean接口定义的销毁方法
void destroyBean(Object existingBean);
//-------------------------------------------------------------------------
// 解决匹配注入点的方法
// 在注入的时候通过以下的方法匹配属性与之对应的bean
//-------------------------------------------------------------------------
/**
* 解析唯一匹配给定对象类型(如果有的话)的bean实例,包括它的bean名称。
* 比如我们调用getBean(User.class) 会匹配一个或多个bean,需要该方法进行选择
* 这实际上是getBean(Class)的一个变体。
*/
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
/**
* 解析给定bean名称的bean实例, 向目标工厂方法公开提供依赖描述符。
* 这实际上是getBean(String, Class)的一个变体,
*/
Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
/**
* 针对此工厂中定义的bean解析指定的依赖项,注入的时候很有用。
* 通过一个依赖的描述(对方法,字段,构造器的抽象),获得一个bean
*/
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
}
BeanFactory 的 子接口:
ApplicationContext
,但是在 ApplicationContext 上下文中,可以通过 ApplicationContext#getAutowireCapableBeanFactory
获取该实例,当然也可以直接获取 BeanFactory 进行类型转换。它是 HierarchicalBeanFactory
的子接口,在基础能力和分层能力之上拓展了配置能力,这是 Spring 常用的类设计模式,这一层抽象了所有 BeanFactory
类相关组件的维护,比如:
BeanExpressionResolver
:SpEL
解析器ConversionService
:转换服务TypeConverter
:类型转换的顶层接口,相当于整合了 ConversionService
和 PropertyEditorRegistry
BeanPostProcessor
:支持添加 BeanPostProcessor
对 bean实例
进行后处理public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
// 标准单例作用域的范围标识符:"singleton".自定义作用域可以通过 registerScope 添加
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
// 设置此 bean 工厂的父级
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
// 将 classLoader 设置为加载中的 bean 类,默认是线程上下文类装入器
void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
// 返回这个工厂的classLoader,用于加载bean类
@Nullable
ClassLoader getBeanClassLoader();
/**
* 指定一个临时ClassLoader用于类型匹配,默认为none。
* 如果涉及到加载时织入,则通常只指定临时ClassLoader,以确保实际的bean类尽可能延迟地加载。
* 一旦BeanFactory完成引导阶段,临时加载器就会被移除。
*/
void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
// 返回用于类型匹配的临时ClassLoader,
ClassLoader getTempClassLoader();
/**
设置是否缓存bean元数据,例如给定的bean定义(以合并的方式)和 resolved bean classes
关闭此标志可启动 bean Definition 和 特定bean类的热刷新
如果该标志关闭,则任何bean实例的创建都将重新查询 bean class Loader 以获得新解析的类。
**/
void setCacheBeanMetadata(boolean cacheBeanMetadata);
boolean isCacheBeanMetadata();
// 设置和获取SpEL表达式解析器
void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
@Nullable
BeanExpressionResolver getBeanExpressionResolver();
// 设置和获取转化服务
void setConversionService(@Nullable ConversionService conversionService);
@Nullable
ConversionService getConversionService();
// 添加属性编辑器
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
// 配置和获取类型转化器,相当于整合了 ConversationService 和 PropertyEditorRegister
void setTypeConverter(TypeConverter typeConverter);
TypeConverter getTypeConverter();
// 为注入的值添加一个String解析器,如“aa${bb}cc”。
void addEmbeddedValueResolver(StringValueResolver valueResolver);
boolean hasEmbeddedValueResolver();
String resolveEmbeddedValue(String value);
// 添加和获取bean的后置处理器
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
int getBeanPostProcessorCount();
// 注册自定义的作用范围
void registerScope(String scopeName, Scope scope);
String[] getRegisteredScopeNames();
@Nullable
Scope getRegisteredScope(String scopeName);
// 为这个bean工厂设置{ApplicationStartup} 用来记录启动步骤
void setApplicationStartup(ApplicationStartup applicationStartup);
ApplicationStartup getApplicationStartup();
// 从一个bean工厂进行拷贝配置
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
// 注册别名
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
// 获取合并的bean的定义(RootBeanDefinition)
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 是否是工厂bean
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
// 控制指定bean当前的创建状态,仅供容器内部使用
void setCurrentlyInCreation(String beanName, boolean inCreation);
// 判断该bean是否在创建中
boolean isCurrentlyInCreation(String beanName);
// 为给定的bean注册一个依赖bean,在给定的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
// 包括已注册一次性的内部bean。
void destroySingletons();
ConfigurableListableBeanFactory
把以上功能都整合在了一起,且拓展了核心方法 preInstantiateSingletons
.
该方法用于在实例化 Bean 之前提前实例化单例Bean的,它首先迭代所有单例 Bean 的定义并检查是否是非延迟初始化的,并且如果是工厂 Bean,则还会检查是否需要提前初始化。然后,它会触发所有适用的Bean的后期初始化回调,并执行。
BeanFactory
:顶层接口,提供了最基础的方法,譬如:getBean、containBean
HierarchicalBeanFactory
,子接口,拓展了 层次关系
ListableBeanFactory
,子接口,拓展了 枚举
能力AutowireCapableBeanFactory
,子接口,拓展了 自动装配
能力ConfigurableBeanFactory
,子接口,拓展了相关组件 可配置化
的能力ConfigurableListableBeanFactory
,集大成者,直接实现类是 DefaultListableBeanFactory。参考文献:
【源码】Spring —— BeanFactory 解读 1 BeanFactory 系列接口