spring源码1 : 核心概念

66 阅读28分钟
1. BeanDefinition

BeanDefinition表示Bean定义,Spring根据BeanDefinition来创建Bean对象,BeanDefinition有很多的属性用来描述Bean,BeanDefinition是Spring中非常核心的概念.

A BeanDefinition describes a bean instance, which has property values,
constructor argument values, and further information supplied by
concrete implementations.
翻译:
BeanDefinition描述了一个bean实例,包括属性值、构造函数参数值,由具体实现提供更进一步的信息


<p>This is just a minimal interface: The main intention is to allow a
{@link BeanFactoryPostProcessor} to introspect and modify property values
and other bean metadata.
翻译:
这只是一个最小的接口:主要目的是允许BeanFactoryPostProcessor内省和修改属性值和其他bean元数据。

总而言之:BeanDefinition就是主要提供描述bean和修改bean的信息的一个接口对象。 BeanDefinition主要是记录了哪些描述信息,主要是通过哪些属性来描述Bean的呢?

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
   /**
    * Scope identifier for the standard singleton scope: {@value}.
    * <p>Note that extended bean factories might support further scopes.
    * 标准单例作用域的作用域标识符
    * 扩展的bean工厂可能支持更多的作用域
    * SCOPE_SINGLETON:单例标识符
    */
   String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

   /**
    * Scope identifier for the standard prototype scope: {@value}.
    * <p>Note that extended bean factories might support further scopes.
    * 标准原型作用域的作用域标识符
    * 扩展的bean工厂可能支持更多的作用域
    * SCOPE_PROTOTYPE:原型标识符
    */
   String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

   /**
    * Role hint indicating that a {@code BeanDefinition} is a major part
    * of the application. Typically corresponds to a user-defined bean.
    * 角色提示,指示BeanDefinitions是应用程序的主要部分
    * 常对应于用户定义的bean
    */
   int ROLE_APPLICATION = 0; //标识Bean的类别:对应用户定义的Bean

   /**
    * Role hint indicating that a {@code BeanDefinition} is a supporting
    * part of some larger configuration, typically an outer
    * 角色提示.指示BeanDefinition是支持某些较大配置的一部分.通常为外部
    */
   int ROLE_SUPPORT = 1;    //标识Bean的类别:来源于配置文件的Bean

   /**
    * Role hint indicating that a {@code BeanDefinition} is providing an
    * entirely background role and has no relevance to the end-user. This hint is
    * used when registering beans that are completely part of the internal workings
    * of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
    * 角色提示,指示BeanDefinition正在提供完全是后台角色,与最终用户无关
    * 此提示是注册完全属于内部工作的bean时使用
    */
   int ROLE_INFRASTRUCTURE = 2; //标识Bean的类别:Spring内部的Bean


   // Modifiable attributes 可修改属性
   
   /**
    * Set the name of the parent definition of this bean definition, if any.
    * 设置此bean定义的父定义的名称(如果有的话)
    */
   void setParentName(@Nullable String parentName);

   /**
    * Return the name of the parent definition of this bean definition, if any.
    * 返回此bean定义的父定义的名称
    */
   @Nullable
   String getParentName();

   /**
    * Specify the bean class name of this bean definition.
    * <p>The class name can be modified during bean factory post-processing,
    * typically replacing the original class name with a parsed variant of it.
    * 指定此bean定义的bean类名。
    * 类名可以在bean工厂后处理期间修改,
    * 通常用解析后的类名变体替换原始类名
    */
   void setBeanClassName(@Nullable String beanClassName);

   /**
    * Return the current bean class name of this bean definition.
    * 返回此bean定义的当前bean类名
    */
   @Nullable
   String getBeanClassName();

   /**
    * Override the target scope of this bean, specifying a new scope name.
    * 此bean的目标作用域,指定一个新的作用域名称
    */
   void setScope(@Nullable String scope);

   /**
    * Return the name of the current target scope for this bean,
    * or {@code null} if not known yet.
    * 返回Bean的作用域
    */
   @Nullable
   String getScope();

   /**
    * Set whether this bean should be lazily initialized.
    * 设置是否应延迟初始化此bean(懒加载)
    * 如果为false,bean将在启动时被bean实例化,执行单实例的快速初始化的工厂
    */
   void setLazyInit(boolean lazyInit);

   /**
    * Return whether this bean should be lazily initialized, i.e. not
    * eagerly instantiated on startup. Only applicable to a singleton bean.
    * 返回此bean是否应延迟初始化,即不启动时急切地实例化。仅适用于单例bean
    */
   boolean isLazyInit();

   /**
    * Set the names of the beans that this bean depends on being initialized.
    * The bean factory will guarantee that these beans get initialized first.
    * 设置此bean所依赖的初始化bean的名称
    * bean工厂将保证首先初始化这些bean
    */
   void setDependsOn(@Nullable String... dependsOn);

   /**
    * Return the bean names that this bean depends on.
    * 返回此bean所依赖的bean名称
    */
   @Nullable
   String[] getDependsOn();

   /**
    * Set whether this bean is a candidate for getting autowired into some other bean.
    * 设置此bean是否是自动连接到其他bean的候选
    * 设置Bean是否可以自动注入.只对@Autowired注解有效
    */
   void setAutowireCandidate(boolean autowireCandidate);

   /**
    * Return whether this bean is a candidate for getting autowired into some other bean.
    返回此bean是否可以自动连接到其他bean(是否可以自动注入)
    */
   boolean isAutowireCandidate();

   /**
    * Set whether this bean is a primary autowire candidate.
    * <p>If this value is {@code true} for exactly one bean among multiple
    * matching candidates, it will serve as a tie-breaker.
    * 设置当前 Bean是否为主要候选Bean
    * 当同一个接口有多个实现类时,通过该属性来配置某个Bean为主候选Bean
    */
   void setPrimary(boolean primary);

   /**
    * Return whether this bean is a primary autowire candidate.
    * 返回此bean是否是主要的autowire候选
    */
   boolean isPrimary();

   /**
    * Specify the factory bean to use, if any.
    * This the name of the bean to call the specified factory method on.
    * 指定要使用的工厂bean(如果有)
    * 设置返回创建该Bean的工厂类
    */
   void setFactoryBeanName(@Nullable String factoryBeanName);

   /**
    * Return the factory bean name, if any.
    * 返回创建该Bean的工厂类
    */
   @Nullable
   String getFactoryBeanName();

   /**
    * Specify a factory method, if any. 
    * 设置创建该Bean的工厂方法
    */
   void setFactoryMethodName(@Nullable String factoryMethodName);

   /**
    * Return a factory method, if any.
    * 返回创建该Bean的工厂方法
    */
   @Nullable
   String getFactoryMethodName();

   /**
    * Return the constructor argument values for this bean.
    * 返回该Bean构造方法参数值
    */
   ConstructorArgumentValues getConstructorArgumentValues();

   /**
    * Return if there are constructor argument values defined for this bean.
    * 返回此bean是否定义了构造函数参数值
    */
   default boolean hasConstructorArgumentValues() {
      return !getConstructorArgumentValues().isEmpty();
   }

   /**
    * Return the property values to be applied to a new instance of the bean.
    * 返回该Bean的所有属性
    */
   MutablePropertyValues getPropertyValues();

   /**
    * Return if there are property values defined for this bean.
    * 返回此bean是否定义了属性值
    */
   default boolean hasPropertyValues() {
      return !getPropertyValues().isEmpty();
   }

   /**
    * Set the name of the initializer method.
    * 设置初始化方法
    */
   void setInitMethodName(@Nullable String initMethodName);

   /**
    * Return the name of the initializer method.
    * 返回初始化方法名
    */
   @Nullable
   String getInitMethodName();

   /**
    * Set the name of the destroy method.
    * 设置销毁方法
    */
   void setDestroyMethodName(@Nullable String destroyMethodName);

   /**
    * Return the name of the destroy method.
    * 返回销毁方法名
    */
   @Nullable
   String getDestroyMethodName();

   /**
    * Set the role hint for this {@code BeanDefinition}. The role hint
    * provides the frameworks as well as tools an indication of
    * the role and importance of a particular {@code BeanDefinition}.
    * 设置此BeanDefinition的角色提示
    */
   void setRole(int role);

   /**
    * Get the role hint for this {@code BeanDefinition}. The role hint
    * provides the frameworks as well as tools an indication of
    * the role and importance of a particular {@code BeanDefinition}.
    * 获取此BeanDefinition的角色提示
    */
   int getRole();

   /**
    * Set a human-readable description of this bean definition.
    * 设置此bean定义的可读描述
    */
   void setDescription(@Nullable String description);

   /**
    * Return a human-readable description of this bean definition.
    * 返回此bean定义的可读描述
    */
   @Nullable
   String getDescription();


   // Read-only attributes 只读属性

   /**
    * Return a resolvable type for this bean definition,
    * based on the bean class or other specific metadata.
    * 基于bean类或其他特定元数据,返回此bean定义的可解析类型
    */
   ResolvableType getResolvableType();

   /**
    * Return whether this a <b>Singleton</b>, with a single, shared instance
    * returned on all calls.
    * 返回这是否是一个Singleton,所有调用都返回一个共享实例。
    */
   boolean isSingleton();

   /**
    * Return whether this a <b>Prototype</b>, with an independent instance
    * returned for each call.
    * 返回这是否是一个原型,并为每个调用返回一个独立的实例。
    */
   boolean isPrototype();

   /**
    * Return whether this bean is "abstract", that is, not meant to be instantiated.
    * 返回这个bean是否是“抽象”的,也就是说,不是要实例化的。
    */
   boolean isAbstract();

   /**
    * Return a description of the resource that this bean definition
    * came from (for the purpose of showing context in case of errors).
    * 返回此bean定义来源的资源的描述(用于在出现错误时显示上下文)。
    */
   @Nullable
   String getResourceDescription();

   /**
    * Return the originating BeanDefinition, or {@code null} if none.
    * <p>Allows for retrieving the decorated bean definition, if any.
    * <p>Note that this method returns the immediate originator. Iterate through the
    * originator chain to find the original BeanDefinition as defined by the user.
    * 返回原始BeanDefinition或null如果没有。
    * 允许检索修饰的bean定义(如果有的话)。
    * 注意,此方法返回直接发起者。遍历发起者链以找到用户定义的原始BeanDefinition
    */
   @Nullable
   BeanDefinition getOriginatingBeanDefinition();

}

我们创建bean有两种方式,一种是通过xml配置一个bean;或者使用@Bean、@Service等注解来定义Bean,spring底层会将配置文件或者注解解析成一个BeanDefinition,之后再通过BeanDefinition对象生成对应的实例化对象,并不会直接生成一个实例化对象.

那么我们知道spring实例化对象是通过beanDefinition来创建的,所以,我们也可以手动创建一个beanDefinition,然后让spring生成一个Bean对象.

public static void main(String[] args) {
   DefaultListableBeanFactory context = new DefaultListableBeanFactory();
   // 1. 实例化一个RootBeanDefinition
   GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
   // 2. 设置 BeanClass
   beanDefinition.setBeanClass(User.class);
   // 3. 设置scope为单例/原型
   // beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
   beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
   // 4. 设置构造方法对应的属性值(User类必须有构造方法否则就会报错)
   ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
   constructorArgumentValues.addGenericArgumentValue(1L);
   constructorArgumentValues.addGenericArgumentValue("username");
   beanDefinition.setConstructorArgumentValues(constructorArgumentValues);
   // 5. 将自定义的beanDefinition注册到Spring容器中
   context.registerBeanDefinition("user", beanDefinition);
   // 6. 通过getBean获取我们定义的类型的实例对象,这个方法在获取实例对象时,如果没有这个对象,就会创建
   User user1 = context.getBean(User.class);
   User user2 = (User) context.getBean("user");
   System.out.println(user1);
   System.out.println(user2);
}
2.BeanDefinitionReader

BeanDefinitionReader是一个BeanDefinition读取器的接口,实现了该接口的Reader可以从不同的资源文件中加载bean到beanFactory中.

BeanDefinitionReaderBeanDefinition的读取器,用于注册beanDefinition,提供了注册、获取资源加载器、获取类加载器、beanname生成、加载beanDefinition等接口.

Simple interface for bean definition readers.
Specifies load methods with Resource and String location parameters.
Concrete bean definition readers can of course add additional load 
and register methods for bean definitions, specific to their bean definition format.
翻译:
bean定义读取器的简单接口,使用Resource和字符串location参数指定要加载的bean定义的资源位置
具体的bean定义reader可以添加额外的负载和注册bean定义的方法,特定于它们的bean定义格式.

Note that a bean definition reader does not have to implement this interface.
It only serves as suggestion for bean definition readers that want to follow standard naming conventions.
翻译:
注意,bean定义读取器不必实现这个接口.
它仅作为希望遵循标准命名约定的bean定义读者的建议。

BeanDefinitionReader的作用是读取Spring配置文件中的内容,将其转换为IOC容器内部的数据结构BeanDefinition,就是使用ResouceLoad将配置信息解析成一个个BeanDefinition,最终借助BeanDefinitionRegistry接口将BeanDefinition注册到容器当中.

2.1. 接口定义
public interface BeanDefinitionReader {
   /**
    * Return the bean factory to register the bean definitions with.
    * 返回Bean工厂以向其注册Bean定义
    *
    * <p>The factory is exposed through the BeanDefinitionRegistry interface,
    * encapsulating the methods that are relevant for bean definition handling.
    * 工厂通过BeanDefinitionRegistry接口公开,封装与bean定义处理相关的方法
    */
   BeanDefinitionRegistry getRegistry();

   /**
    * Return the resource loader to use for resource locations.
    * Can be checked for the <b>ResourcePatternResolver</b> interface and cast
    * accordingly, for loading multiple resources for a given resource pattern.
    * 返回资源加载器以用于资源位置.可以检查ResourcePatternResolver接口并进行相应的转换,
    * 以针对给定的资源模式加载多个资源.
    * 一个null返回值表明,绝对资源加载不适用于这个bean定义阅读器。
    * 这主要用于从bean定义资源中导入其他资源,例如,通过XML bean定义中的“import”标记.
    * 但是,建议相对于定义资源应用此类导入;只有明确的完整资源位置才会触发绝对资源加载
    */
   @Nullable
   ResourceLoader getResourceLoader();

   /**
    * Return the class loader to use for bean classes.
    * 返回用于Bean类的类加载器
    */
   @Nullable
   ClassLoader getBeanClassLoader();

   /**
    * Return the BeanNameGenerator to use for anonymous beans
    * (without explicit bean name specified).
    * 返回BeanNameGenerator用于匿名Bean(未指定显式Bean名称)
    */
   BeanNameGenerator getBeanNameGenerator();

   /**
    * Load bean definitions from the specified resource.
    * 从指定的资源加载bean定义
    */
   int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;

   /**
    * Load bean definitions from the specified resources.
    * 从指定的资源加载bean定义
    */
   int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;

   /**
    * Load bean definitions from the specified resource location.
    * 从指定的资源位置加载bean定义
    * The location can also be a location pattern, provided that the
    * ResourceLoader of this bean definition reader is a ResourcePatternResolver.
    * 该位置也可以是位置模式,前提是此bean定义读取器的ResourceLoader是ResourcePatternResolver
    */
   int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;

   /**
    * Load bean definitions from the specified resource locations.
    * 从指定的资源位置加载bean定义
    */
   int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}
2.2 结构图

image.png

(1)AbstractBeanDefinitionReader:实现了EnvironmentCapable,提供了获取/设置环境的方法.定义了一些通用方法,使用策略模式,将一些具体方法放到子类实现.

(2)XmlBeanDefinitionReader:读取XML文件定义的BeanDefinition

(3)PropertiesBeanDefinitionReader:可以从属性文件,Resource,Property对象等读取 BeanDefinition

(4)GroovyBeanDefinitionReader:可以读取Groovy语言定义的Bean

2.3 模拟使用BeanDefinitionReader读取spring配置,将其解析成BeanDefinition

对应BeanDefinition定义方式,它也有2种读取方式.

(1)XmlBeanDefinitionReader:扫描标签

(2)AnnotatedBeanDefinitionReader:扫描由注解定义的类,能够解析的注解:@Conditional,@Scope,@Lazy,@Primary,@DependsOn,@Role,@Description

(3)还有一个读取方式,就是ClassPathBeanDefinitionScanner,和上面两个一样,多了一个路径扫描,并将扫描到的含有注解的类注册

public static void main(String[] args) {
   // 扫描xml注册bean
   DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
   XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(beanFactory);
   int i = xmlReader.loadBeanDefinitions("spring.xml");  // 核心方法
   User user = (User)beanFactory.getBean("user");
   System.out.println(user);

   // 扫描配置类注册bean
   AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(beanFactory);
   reader.register(User.class);           // 核心方法
   User user2 = beanFactory.getBean(User.class);
   System.out.println(user2);

   // 扫描类路径注册
   ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanFactory);
   int scan = scanner.scan("com.baidu.basic");          // 核心方法
   User user3 = (User) beanFactory.getBean("user");
   System.out.println(user3);
}
3.BeanFactory

BeanFactory是spring的原始接口,针对原始结构的实现类功能比较单一.Beanfacoty负责读取bean的配置文档,管理bean的加载,实例化,维护bean之前的依赖关系,负责bean的生命周期.

BeanFactory接口定义了一个容器所需要具备的工厂接口,它提供一个Bean工厂的基本功能约定,其定制化需求由其扩展子接口进行补充.

每个扩展子接口对应不同的职责,最后由ConfigurableListableBeanFactory做统一的汇总,再由DefaultListableBeanFactory统一实现其中的方法,形成内置的IOC容器,但是注意,BeanFactroy还未达成企业应用级别的容器,但是已经具备了容器的基础能力.

The root interface for accessing a Spring bean container.
用于访问Spring bean容器的根接口

This is the basic client view of a bean container;
这是bean容器的基本客户端视图

further interfaces such as {@link ListableBeanFactory} and
{@link org.springframework.beans.factory.config.ConfigurableBeanFactory} are available for specific purposes.
如ListableBeanFactoryConfigurableBeanFactory可用于特定目的

This interface is implemented by objects that hold a number of bean definitions,
each uniquely identified by a String name. Depending on the bean definition,
the factory will return either an independent instance of a contained object
(the Prototype design pattern), or a single shared instance (a superior
alternative to the Singleton design pattern, in which the instance is a
singleton in the scope of the factory). Which type of instance will be returned
depends on the bean factory configuration: the API is the same. Since Spring
2.0, further scopes are available depending on the concrete application
context (e.g. "request" and "session" scopes in a web environment).
翻译:
这个接口由包含许多bean定义对象的实现,每个bean定义由一个字符串名作为唯一标识.
根据bean定义,工厂将返回包含对象的独立实例(原型设计模式)或单个共享实例(单例设计模式的高级替代方案,其中实例是工厂范围内的单例)
返回哪种类型的实例取决于bean工厂配置:API是相同的。
自Spring2.0以来,根据具体的应用程序上下文,还可以使用更多的作用域(例如web环境中的"request"和"session"作用域).

The point of this approach is that the BeanFactory is a central registry
of application components, and centralizes configuration of application
components (no more do individual objects need to read properties files,
for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and
Development" for a discussion of the benefits of this approach.
翻译:
这种方法的要点是BeanFactory是应用程序组件的中心注册表,并集中配置应用程序组件(例如,单个对象不再需要读取属性文件)
有关这种方法的好处的讨论,请参阅“专家一对一J2EE设计和开发”的第4章和第11Note that it is generally better to rely on Dependency Injection
("push" configuration) to configure application objects through setters
or constructors, rather than use any form of "pull" configuration like a
BeanFactory lookup. Spring's Dependency Injection functionality is
implemented using this BeanFactory interface and its subinterfaces.
翻译:
请注意,通常最好依靠依赖项注入("push"配置)通过setter或构造函数配置应用程序对象,而不是使用任何形式的"pull"配置,
如BeanFactory查找.Spring的依赖项注入功能是使用这个BeanFactory接口及其子接口实现的.

Normally a BeanFactory will load bean definitions stored in a configuration
source (such as an XML document), and use the {@code org.springframework.beans}
package to configure the beans. However, an implementation could simply return
Java objects it creates as necessary directly in Java code. There are no
constraints on how the definitions could be stored: LDAP, RDBMS, XML,
properties file, etc. Implementations are encouraged to support references
amongst beans (Dependency Injection).
翻译:
通常,BeanFactory将加载存储在配置源中的bean定义(例如XML文档),并使用org.springframework.beans包来配置bean.
但是,实现可以简单地返回它根据必要的Java对象直接在Java代码中创建.对于如何存储定义,没有约束:鼓励LDAP,RDBMS,XML,属性文件等实现.
在Bean(依赖项注入)中支持引用

In contrast to the methods in {@link ListableBeanFactory}, all of the
operations in this interface will also check parent factories if this is a
{@link HierarchicalBeanFactory}. If a bean is not found in this factory instance,
the immediate parent factory will be asked. Beans in this factory instance
are supposed to override beans of the same name in any parent factory.
翻译:
与ListableBeanFactory中的方法不同,如果这是HierarchycalBeanFactory,则此接口中的所有操作也将检查父工厂.
如果在此工厂实例中找不到bean,将直接访问父工厂.此工厂实例中的bean会覆盖任何父工厂中同名的bean

Bean factory implementations should support the standard bean lifecycle interfaces
as far as possible. The full set of initialization methods and their standard order is:
Bean Factory实现应尽可能支持标准Bean生命周期接口.全套初始化方法及其标准流程是:
<ol>

<li>BeanNameAware's {@code setBeanName}
<li>BeanClassLoaderAware's {@code setBeanClassLoader}
<li>BeanFactoryAware's {@code setBeanFactory}
<li>EnvironmentAware's {@code setEnvironment}
<li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
<li>ResourceLoaderAware's {@code setResourceLoader}
(only applicable when running in an application context)
<li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
(only applicable when running in an application context)
<li>MessageSourceAware's {@code setMessageSource}
(only applicable when running in an application context)
<li>ApplicationContextAware's {@code setApplicationContext}
(only applicable when running in an application context)
<li>ServletContextAware's {@code setServletContext}
(only applicable when running in a web application context)
<li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
<li>InitializingBean's {@code afterPropertiesSet}
<li>a custom init-method definition
<li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
</ol>

<p>On shutdown of a bean factory, the following lifecycle methods apply:
在关闭bean工厂时,将调用以下方法
<ol>
<li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
<li>DisposableBean's {@code destroy}
<li>a custom destroy-method definition
</ol>
3.1 接口定义
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} is a FactoryBean, getting {@code &myJndiObject}
    * will return the factory, not the instance returned by the factory.
    * 对FactoryBean的转义定义,因为如果使用Bean的名字检索FactoryBean得到的对象是工厂生成的对象,
    * 如果需要得到工厂本身,就需要加上这个转义符
    */
   String FACTORY_BEAN_PREFIX = "&";

   /**
    * Return an instance, which may be shared or independent, of the specified bean. 
    * 返回指定bean的实例,该实例可以是共享的或独立的
    * 根据bean的名字,获取在IOC容器中得到的bean的实例
    *
    * <p>This method allows a Spring BeanFactory to be used as a replacement for the
    * Singleton or Prototype design pattern. Callers may retain references to
    * returned objects in the case of Singleton beans.
    * 此方法允许使用SpringBeanFactory作为Singleton或原型设计模式
    * 在Singleton bean的情况下,调用者可以保留对返回对象的引用
    */
   Object getBean(String name) throws BeansException;

   /**
    * 根据bean名字,获取在IOC容器中的到的Bean的实例,如果bean返回的类型不所需要的
    * 就会抛出BeanNotOfRequiredTypeException异常来提供类型安全性
    */
   <T> T getBean(String name, Class<T> requiredType) throws BeansException;

   /**
    * Return an instance, which may be shared or independent, of the specified bean.
    * 返回指定bean的实例,该实例可以是共享的或独立的
    *
    * <p>Allows for specifying explicit constructor arguments / factory method arguments,
    * overriding the specified default arguments (if any) in the bean definition.
    * 允许指定显式构造函数参数/工厂方法参数,
    * 重写bean定义中指定的默认参数(如果有的话)
    */
   Object getBean(String name, Object... args) throws BeansException;

   /**
    * Return the bean instance that uniquely matches the given object type, if any.
    * 返回唯一匹配给定对象类型的bean实例(如果有的话)
    * 根据bean类型,返回容器中的bean实例,此方法会进入ListtableBeanFactory
    */
   <T> T getBean(Class<T> requiredType) throws BeansException;

   <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

   /**
    * Return a provider for the specified bean, allowing for lazy on-demand retrieval
    * of instances, including availability and uniqueness options.
    * 返回指定bean的提供程序,允许延迟按需检索实例,包括可用性和唯一性选项
    */
   <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

   <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

   /**
    * Does this bean factory contain a bean definition or externally registered singleton
    * instance with the given name?
    * <p>If the given name is an alias, it will be translated back to the corresponding
    * canonical bean name.
    * 这个bean工厂是否包含具有给定名称的bean定义或外部注册的单例实例?
    * 如果给定的名称是别名,它将被转换回对应的规范bean名称
    */
   boolean containsBean(String name);

   /**
    * Is this bean a shared singleton? That is, will {@link #getBean} always
    * return the same instance?
    * 这个bean是共享单例的吗?也就是说,{@link#getBean}是否总是返回相同的实例?
    */
   boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

   /**
    * Is this bean a prototype? That is, will {@link #getBean} always return
    * independent instances?
    * 这个bean是原型吗?也就是说,{@link#getBean}将始终返回独立实例?
    */
   boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

   /**
    * Check whether the bean with the given name matches the specified type.
    * 检查具有给定名称的bean是否与指定类型匹配
    */
   boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

   boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

   /**
    * Determine the type of the bean with the given name. 
    * 确定具有给定名称的bean的类型.
    */
   @Nullable
   Class<?> getType(String name) throws NoSuchBeanDefinitionException;

   @Nullable
   Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;

   /**
    * Return the aliases for the given bean name, if any.
    * 输入bean的名字获取bean的别名,如果给别名,则返回Bean的名字,如果没有则返回空数组
    */
   String[] getAliases(String name);
}
3.2 结构图

image.png (1)AliasRegistry:支持别名功能,一个名字可以对应多个别名

(2)BeanDefinitionRegistry:可以注册,保存,移除,获取某个BeanDefinition

(3)BeanFactory:Bean工厂,可以根据某个bean的名字、或类型、或别名获取某个Bean对象

(4)SingletonBeanRegistry:可以直接注册、获取某个单例Bean

(5)SimpleAliasRegistry:它是一个类,实现了AliasRegistry接口中所定义的功能,支持别名功能

(6)ListableBeanFactory:在BeanFactory的基础上,增加了其他功能,可以获取所有BeanDefinition的beanNames,可以根据某个类型获取对应的beanNames,可以根据某个类型获取{类型:对应的Bean}的映射关系

(7)HierarchicalBeanFactory:在BeanFactory的基础上,添加了获取父BeanFactory的功能

(8)DefaultSingletonBeanRegistry:它是一个类,实现了SingletonBeanRegistry接口,拥有了直接注册、获取某个单例Bean的功能

(9)ConfigurableBeanFactory:在HierarchicalBeanFactory和SingletonBeanRegistry的基础上,添加了设置父BeanFactory、类加载器(表示可以指定某个类加载器进行类的加载)、设置Spring EL表达式解析器(表示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示该BeanFactory可以进行类型转化)、可以添加BeanPostProcessor(表示该BeanFactory支持Bean的后置处理器),可以合并BeanDefinition,可以销毁某个Bean等等功能

(10)FactoryBeanRegistrySupport:支持了FactoryBean的功能

(11)AutowireCapableBeanFactory:是直接继承了BeanFactory,在BeanFactory的基础上,支持在创建Bean的过程中能对Bean进行自动装配

(12)AbstractBeanFactory:实现了ConfigurableBeanFactory接口,继承了FactoryBeanRegistrySupport,这个BeanFactory的功能已经很全面了,但是不能自动装配和获取beanNames

(13)ConfigurableListableBeanFactory:继承了ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactory

(14)AbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory,实现了AutowireCapableBeanFactory,拥有了自动装配的功能

(15)DefaultListableBeanFactory:继承了AbstractAutowireCapableBeanFactory,实现了ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口,所以DefaultListableBeanFactory的功能很强大

4.FactoryBean

FactoryBean:是一个Java Bean,但是它是一个能生产对象的工厂Bean,把IOC容器比作水桶,那么Java Bean就是水桶里面的水,但是这个FactoryBean一种比较特殊的水,可以把它看成是一个水球,这个水球里面也包含了水,我们可以通过IOC取这个水球,但是也可以直接取水球里面的水;(用法就是用&表示取水球,取水球里的水用正常的获取方式就行了;如果我们用&获取到了水球之后,可以通过这个水球的 getObject方法获取水球里面的水;)

FactoryBean是由spring提供的用来让用户可以自定义bean创建的接口;实现该接口可以让你的bean不用经过spring复杂的bean创建过程,但同时也能做到拿来即用,按需加载;

FactoryBean是Spring所提供的一种较灵活的创建Bean的方式,可以通过实现FactoryBean接口中的getObject()方法来返回一个对象,这个对象就是最终的Bean对象

Interface to be implemented by objects used within a {@link BeanFactory} 
which are themselves factories for individual objects. If a bean implements 
this interface, it is used as a factory for an object to expose, not directly 
as a bean instance that will be exposed itself.
翻译:
实现FactoryBean接口的对象就会成为工厂,这些工厂可以生产特定的对象。
如果一个Bean实现了这个接口,它就会被作为一个生产对象工厂暴露在Srping容器中,
而不会直接暴露它可以生产的对象

NB: A bean that implements this interface cannot be used as a normal bean.
A FactoryBean is defined in a bean style, but the object exposed for bean 
references ({@link #getObject()}) is always the object that it creates.
翻译:
注意:实现了这个接口的bean不是普通的bean
一个factorybean以一个bean的方式定义,但是bean引用公开的对象总是他所创建的对象。

FactoryBeans can support singletons and prototypes, and can either create
objects lazily on demand or eagerly on startup. The {@link SmartFactoryBean} 
interface allows for exposing more fine-grained behavioral metadata.
翻译:
factoryBean支持创建单例多例,也可以根据需要创建懒加载的对象或者启动的时候需要创建的对象。
SmartFactoryBean 这个接口允许暴露更多细粒度的行为元数据。


This interface is heavily used within the framework itself, for example for
the AOP {@link org.springframework.aop.framework.ProxyFactoryBean} or 
the {@link org.springframework.jndi.JndiObjectFactoryBean}. 
It can be used for custom components as well; 
however, this is only common for infrastructure code.
翻译:
这个接口被框架本身重度使用,例如aop(ProxyFactoryBean)和JndiObjectFactoryBean,
他也能用来自定义组件。但是这是适用于基础架构代码


{@code FactoryBean} is a programmatic contract. Implementations are not 
supposed to rely on annotation-driven injection or other reflective 
facilities. {@link #getObjectType()} {@link #getObject()} invocations may 
arrive early in the bootstrap process, even ahead of any post-processor setup. 
If you need access to other beans, implement {@link BeanFactoryAware} and 
obtain them programmatically.
翻译:
factoryBean是一个编程契约,实现不应该依赖注解方式注入或者其他反射工具.
里面的方法getObject,getObjectType可能在启动过程提前调用,甚至所有post-processer前面.
如果你需要用其他bean,实现BeanFactoryAware接口,通过编程方式获取

The container is only responsible for managing the lifecycle of the 
FactoryBean instance, not the lifecycle of the objects created by the 
FactoryBean. Therefore, a destroy method on an exposed bean object (such as 
{@link java.io.Closeable#close()} will not be called automatically. Instead, a 
FactoryBean should implement {@link DisposableBean} and delegate any such 
close call to the underlying object.
翻译:
容器只负责管理FactoryBean实例的生命周期,而不是FactoryBean创建的对象的生命周期
推荐实现DisposableBean接口,因为容器只负责FactoryBean的生命周期,
但不负责通过FactoryBean创建的对象的生命周期,所以需要你进行管理

Finally, FactoryBean objects participate in the containing BeanFactory's 
synchronization of bean creation. There is usually no need for internal 
synchronization other than for purposes of lazy initialization within the 
FactoryBean itself (or the like).
翻译:
最后,factorybean的创建参与包含beanFactory的bean的创建同步,内部的同步过程是没必要的,
代替的是factory的自己延迟初始化(或者类似)

4.1 接口定义
public interface FactoryBean<T> {

   /**
    * The name of an attribute that can be
    * {@link org.springframework.core.AttributeAccessor#setAttribute set} on a
    * {@link org.springframework.beans.factory.config.BeanDefinition} so that
    * factory beans can signal their object type when it can't be deduced from
    * the factory bean class.
    * @since 5.2
    */
   String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";


   /**
    * Return an instance (possibly shared or independent) of the object
    * managed by this factory.
    * <p>As with a {@link BeanFactory}, this allows support for both the
    * Singleton and Prototype design pattern.
    * <p>If this FactoryBean is not fully initialized yet at the time of
    * the call (for example because it is involved in a circular reference),
    * throw a corresponding {@link FactoryBeanNotInitializedException}.
    * <p>As of Spring 2.0, FactoryBeans are allowed to return {@code null}
    * objects. The factory will consider this as normal value to be used; it
    * will not throw a FactoryBeanNotInitializedException in this case anymore.
    * FactoryBean implementations are encouraged to throw
    * FactoryBeanNotInitializedException themselves now, as appropriate.
    * @return an instance of the bean (can be {@code null})
    * @throws Exception in case of creation errors
    * @see FactoryBeanNotInitializedException
    * 返回一个被工厂管理的对象,可能是多例或者单例.和beanfactory一样,支持单例多例设计模式.
    * 如果这个factorybean在调用的时候还没完全初始化成功,(例如,包含一个循环依赖),抛出一个     * 相应的FactoryBeanNotInitializedException异常.spring2.0以后,
    * factory允许返回空对象,工厂将把他作为正常值一样使用,这种情况将不再抛出一个
    * FactoryBeanNotInitializedException异常,FactoryBean的实现类将抛出一个
    * FactoryBeanNotInitializedException 异常,视情况而定
    */
   @Nullable
   T getObject() throws Exception;

   /**
    * Return the type of object that this FactoryBean creates,
    * or {@code null} if not known in advance.
    * <p>This allows one to check for specific types of beans without
    * instantiating objects, for example on autowiring.
    * <p>In the case of implementations that are creating a singleton object,
    * this method should try to avoid singleton creation as far as possible;
    * it should rather estimate the type in advance.
    * For prototypes, returning a meaningful type here is advisable too.
    * <p>This method can be called <i>before</i> this FactoryBean has
    * been fully initialized. It must not rely on state created during
    * initialization; of course, it can still use such state if available.
    * <p><b>NOTE:</b> Autowiring will simply ignore FactoryBeans that return
    * {@code null} here. Therefore it is highly recommended to implement
    * this method properly, using the current state of the FactoryBean.
    * @return the type of object that this FactoryBean creates,
    * or {@code null} if not known at the time of the call
    * @see ListableBeanFactory#getBeansOfType
    * 返回FactoryBean创建的对象的类型或者null,如果提前不知道的话,这样就可以在bean没
    * 初始化的时候监测bean的具体类型,例如autowiring.
    * 在接口实现类正在创建一个单例对象的时候,这个方法应该尽力避免单例对象的创建,而是提前预测
    *这个对象的类型.
    * 对于多例的对象,也建议在这返回一个有意义的对象类型.这个方法可以在这个factorybean完全
    * 初始化之前调用.在初始化的过程中不是强依赖于创建状态的,当然,如果这些状态存在也可以使用
    * 注意:antowireing 将简单的忽略返回null的factoryBean,因此强烈要求正确实现这个方法
    * 用这个factorybean的当前状态,返回:这个factorybean创建的对象类型,如果调用的时候还不
    * 知道的话返回null.
    */
   @Nullable
   Class<?> getObjectType();

   /**
    * Is the object managed by this factory a singleton? That is,
    * will {@link #getObject()} always return the same object
    * (a reference that can be cached)?
    * <p><b>NOTE:</b> If a FactoryBean indicates to hold a singleton object,
    * the object returned from {@code getObject()} might get cached
    * by the owning BeanFactory. Hence, do not return {@code true}
    * unless the FactoryBean always exposes the same reference.
    * <p>The singleton status of the FactoryBean itself will generally
    * be provided by the owning BeanFactory; usually, it has to be
    * defined as singleton there.
    * <p><b>NOTE:</b> This method returning {@code false} does not
    * necessarily indicate that returned objects are independent instances.
    * An implementation of the extended {@link SmartFactoryBean} interface
    * may explicitly indicate independent instances through its
    * {@link SmartFactoryBean#isPrototype()} method. Plain {@link FactoryBean}
    * implementations which do not implement this extended interface are
    * simply assumed to always return independent instances if the
    * {@code isSingleton()} implementation returns {@code false}.
    * <p>The default implementation returns {@code true}, since a
    * {@code FactoryBean} typically manages a singleton instance.
    * @return whether the exposed object is a singleton
    * @see #getObject()
    * @see SmartFactoryBean#isPrototype()
    * 这个工厂管理的对象是单例的么?如果是,那么getobject方法会一直返回同一个对象.
    * 注意:如果一个factoryBean只是保存的是单例对象,那么getobject获得的对象可能会被拥有的
    * beanfactory缓存.因此,不要返回true,除非factory bean老是公开同样的对象引用.
    * 这个factoryBean本身的单例状态通常有所拥有的的beanFactory提供,通常它必须是单例
    * 状态.注意:这个方法返回false 并不一定说明返回的对象是多例的,一个扩展的接口实现
    * SmartFactoryBean有个方法isPrototype可以明确指示这个返回的对象是多例的.没有实现这
    * 个扩展接口的普通接口实现类似(factortyBean),如果isSingleton返回false,只是假设每
    * 次返回独立实例。因为factoryBean常见管理一个单例实例,所以接口默认返回false。
    */
   default boolean isSingleton() {
      return true;
   }

}
4.2 解释误区

FactoryBean是一个顶层接口,实现了该接口的类的实例叫做factory bean也就是工厂bean,读音相同但是含义完全不同,我们通常说的factoryBean其实指的就是实现了FactoryBean接口创建的factory bean.

image.png

4.3 BeanFactory与FactoryBean的区别

BeanFactoryFactoryBean都是Spring中的一个顶层接口, BeanFactory是Spring中的一个Bean工厂,它用于生产bean,获取Bean; FactoryBean他是一个Bean,是Spring容器管理的,当然,他不是一个普通Bean,是一个特殊的Bean;

我们创建一个类,并且添加到Spring容器中,实现FactoryBean的三个方法,而这三个方法就决定了他不是一个普通bean,FactoryBean中有三个方法,分别是getObject,getObjectType以及isSingleton,getObject是用于返回一个对象,并且这个对象会交给Spring容器管理,

也就是说,实现了FactoryBean接口的bean他不是一个普通的bean,他是一个可以生产出一个bean对象的工厂bean,getObjectType用于返回生产的bean的Class对象,isSingleton是表示在这个bean是否单例,它的返回值是boolean类型,为true就是单例,false就是多例(prototype),

而且,在Spring容器中,这两个bean的beanName也是有所区别的,假如A实现了FactoryBean,并且配置A的BeanName为 a,在getObject中返回对象B,当通过容器根据beanName a 获取到的对象不会是A对象,而是A类中getObject返回的对象,当需要A对象时,需要在a前面加上一个&符号才能获取到,也就说A对象的beanName为&a,;

FactoryBean在Mybatis的spring整合包中就有所应用,Mybatis提供的SqlSessionFactoryBean就是实现了FactoryBean接口,用于生产SqlSessionFactory对象,这个对象spring容器中是单例的,因为isSingleton中返回的是true,SqlSessionFactoryBean就是Mybatis提供的一个用于Spring整合Mybatis的一个入口