【Spring源码分析】BeanFactory系列接口解读

认识Bean工厂

  • 一、认识Bean工厂
    • BeanFactory
    • ListableBeanFactory
    • HierarchicalBeanFactory
    • AutowireCapableBeanFactory
    • ConfigurableBeanFactory
    • ConfigurableListableBeanFactory
  • 二、总结

一、认识Bean工厂

Spring Bean 工厂是Spring框架提供的一种机制,用于创建和管理对象(或称为Bean)。它是Spring框架的核心部分,提供了一种灵活、可配置的方式来管理对象的生命周期和依赖关系

下面展示了整个 Bean 工厂的常见接口和类以及功能(其中 XmlBeanFactory 已经被弃用):

【Spring源码分析】BeanFactory系列接口解读_第1张图片

1、不同的接口展现了不同的能力,是对子类能力的抽象;

2、 抽象类构建通用方法的实现,是通用核心方法的具体实现;

3、 具体类完成特定功能的实现,是特定功能的具体实现;

BeanFactory

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 的时候,就会报以下异常:

【Spring源码分析】BeanFactory系列接口解读_第2张图片

此时 ObjectProvider 就提供了它的作用了:

@Service
public class UserService {

    UserDao userDao;

    public UserService(ObjectProvider<UserDao> objectProvider) {
        // 如果容器中存在就返回,不存在返回null
        this.userDao = objectProvider.getIfUnique();
    }

}

【Spring源码分析】BeanFactory系列接口解读_第3张图片

这样注入的好处很明显,就是如果容器中不存在 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;

}

ListableBeanFactory

该工厂继承自 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

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 用于获取父 BeanFactory
  • containsLocalBean 不同于 BeanFactory#containsBean,只会在当前层级中判断是否存在指定 namebean实例.

AutowireCapableBeanFactory

这个接口提供了构建和自动装配的能力,主要是赋予子类自动装配的能力,是容器最核心的接口,这个接口定义了 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 的 子接口:

  • 拓展了 自动注入 等相关能力
  • 它的能力被单独拎出来,因此允许非 Spring 组件的实例也借助它来实现自动装配;
  • 它的功能没有暴露给 ApplicationContext,但是在 ApplicationContext 上下文中,可以通过 ApplicationContext#getAutowireCapableBeanFactory 获取该实例,当然也可以直接获取 BeanFactory 进行类型转换。
  • 它定义了不同的粒度生命周期的相关方法,基于主要的几个里程碑比如 实例的创建 属性的填充 初始化回调 来划分,一般 Spring 内部自然是对 bean 实例执行全过程的生命周期。

ConfigurableBeanFactory

它是 HierarchicalBeanFactory 的子接口,在基础能力和分层能力之上拓展了配置能力,这是 Spring 常用的类设计模式,这一层抽象了所有 BeanFactory 类相关组件的维护,比如:

  • BeanExpressionResolverSpEL 解析器
  • ConversionService:转换服务
  • TypeConverter:类型转换的顶层接口,相当于整合了 ConversionServicePropertyEditorRegistry
  • BeanPostProcessor:支持添加 BeanPostProcessorbean实例 进行后处理
  • 等等
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

ConfigurableListableBeanFactory 把以上功能都整合在了一起,且拓展了核心方法 preInstantiateSingletons.

该方法用于在实例化 Bean 之前提前实例化单例Bean的,它首先迭代所有单例 Bean 的定义并检查是否是非延迟初始化的,并且如果是工厂 Bean,则还会检查是否需要提前初始化。然后,它会触发所有适用的Bean的后期初始化回调,并执行。

二、总结

  • BeanFactory:顶层接口,提供了最基础的方法,譬如:getBean、containBean
  • HierarchicalBeanFactory,子接口,拓展了 层次关系
  • ListableBeanFactory,子接口,拓展了 枚举 能力
  • AutowireCapableBeanFactory,子接口,拓展了 自动装配 能力
  • ConfigurableBeanFactory,子接口,拓展了相关组件 可配置化 的能力
  • ConfigurableListableBeanFactory,集大成者,直接实现类是 DefaultListableBeanFactory。

参考文献:

【源码】Spring —— BeanFactory 解读 1 BeanFactory 系列接口

你可能感兴趣的:(Java源码分析,spring,原型模式,javascript)