转载

探索SpringBoot-一起看看Spring核心源码之BeanFactory(七)

上篇讲解了 探索SpringBoot-一起来看看Spring容器加载核心源码(六) ,讲解到要 探索obtainFreshBeanFactory() 函数,但是不了解 Spring容器 的设计理念是没有办法来理解 obtainFreshBeanFactory() 函数的,所以今天来看看 Spring容器 最最基本的接口设计 BeanFactory

ClassPathXmlApplicationContext引出的类继承关系

接着我们的 探索SpringBoot-一起来看看Spring容器加载核心源码(六) 中的 ClassPathXmlApplicationContext ,我们打开 Idea 并且打开这个源代码文件,并且右键依次点击 Diagrams -> show Diagrams ,最后我们可以得到一张非常神奇的图。(我感觉很多人都不知道 idea 能够做到这个事情,不知道的举手,hahah)

探索SpringBoot-一起看看Spring核心源码之BeanFactory(七)

从上图中,我们可以清晰地看到最中心的接口是 ApplicationContext ,最底层的接口是 BeanFacotry 今天暂时先不管 ApplicationContext ,因为我们必须先理解了 BeanFactory 之后,才能理解 ApplicationContext

BeanFactory

然后,我们打开 BeanFactory ,翻到源代码对 BeanFactory 的注释。

* The root interface for accessing a Spring bean container.
 * 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 容器的根接口。这个是对于bean容器来说最基本的客户视图。像其他ConfigurableBeanFactory和ListableBeanFactory都是为了特定的功能提供的

在《Spring技术内幕》中也这样解释到

BeanFactory提供的是最基本的IoC容器的功能,BeanFactory接口定义了IoC容器最基本的形式,并且提供了IoC容器所应该遵守的最基本的服务契约,也是我们使用IoC容器所应遵守的最底层和最基本的编程规范,这些接口定义勾画了Ioc的基本轮廓。

让我们来看看 BeanFactory 的接口定义是什么样子的?

public interface BeanFactory {

	/**
	 * Used to dereference a {@link FactoryBean} instance and distinguish it from
	 * beans <i>created</i> by the FactoryBean. For example, if the bean named
	 * <code>myJndiObject</code> is a FactoryBean, getting <code>&myJndiObject</code>
	 * will return the factory, not the instance returned by the factory.
	 */
	String FACTORY_BEAN_PREFIX = "&";
	
        //1.从容器中获取指定的Bean
	Object getBean(String name) throws BeansException;

	Object getBean(String name, Class requiredType) throws BeansException;

	Object getBean(String name, Object[] args) throws BeansException;
        //2.判断容器是否包含了指定的Bean
	boolean containsBean(String name);
        //3.判断指定的Bean是否是Singleton的
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
        //4.判断指定的Bean是否是Prototype的
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
        //5.判断指定的Bean的Class类型是否是特定的Class类型
	boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;
        //6.获取指定名字Bean的Class类型
	Class getType(String name) throws NoSuchBeanDefinitionException;
        //7.查询指定Bean的所有的别名
	String[] getAliases(String name);

}
复制代码

从详细的注释中可以看到总共定义了7个方法,这些方法勾画出IoC容器的基本特性。用大白话讲就是容器起码得有这几个方法才能算是一个基本的,合格的容器。

在这个基础上, Spring 还提供了一系列符合Ioc的容器工开发人员使用。其中 DefaultListableBeanFactorySpring 提供的一个实现 Ioc 容器的最最基本的实现类。依照惯例,我们也来看看 DefaultListableBeanFactory 的继承类图。

探索SpringBoot-一起看看Spring核心源码之BeanFactory(七)

通过上图,我们可以看到 DefaultListableBeanFactory 一方面是实现了左侧以 BeanFactory 为根的接口,右侧是实现 BeanDefinitionRegistry 接口。打开该类的源代码,我们也可以看到这么一段话。

/**
 * Default implementation of the
 * {@link org.springframework.beans.factory.ListableBeanFactory} and
 * {@link BeanDefinitionRegistry} interfaces: a full-fledged bean factory
 * based on bean definition objects.
 *
复制代码

大意是这是一个 实现了 ListableBeanFactoryBeanDefinitionRegistry 的完整的 bean 定义的对象。理解就是这是一个最基本的,但是也是可用的BeanFacotry实现

那么具体是怎么实现的呢? 且听下回分解。

关于写作

以后这里每天都会写一篇文章,题材不限,内容不限,字数不限。尽量把自己每天的思考都放入其中。

如果这篇文章给你带来了帮助,能请你写下是哪个部分吗?有效的反馈是对我最大的帮助。

我是shane。今天是2019年8月12日。百天写作计划的第十九天,19/100。

原文  https://juejin.im/post/5d5172455188257bc15d3204
正文到此结束
Loading...