目 录CONTENT

文章目录

BeanFactory接口注释阅读

在水一方
2022-02-20 / 0 评论 / 0 点赞 / 407 阅读 / 6,586 字 / 正在检测是否收录...

前言

平时用spring忙着进行业务开发,对于这个BeanFactory接口看了很多篇文章介绍,但是感觉还是对它停留在表面,还是觉得要静下来一步一步的学习,那就先从阅读BeanFactory的接口注释说明开始吧,注释代表的是官方也是最权威的

阅读源码方法论

1 不要忽视源码注释,一定要尝试看注释
2 不要一开始就深入细节,死抠某个方法,先梳理脉络,然后看细节
3 大胆猜测,一开始不知道作者是怎么想的,可以大胆猜测,大胆验证
4 见名知义
5 然后就是不断坚持

BeanFactory接口的方法

位于:package org.springframework.beans.factory

public interface BeanFactory {
	String FACTORY_BEAN_PREFIX = "&";
	Object getBean(String name) throws BeansException;
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	<T> T getBean(Class<T> requiredType) throws BeansException;
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
	boolean containsBean(String name);

	
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

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

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

	String[] getAliases(String name);

}

先来看看注释是怎么说的:
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
更多接口例如ListableBeanFactory和ConfigurableBeanFactory可用于特定目的

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是相同的。自Spring 2.0以来,根据具体的应用程序上下文(例如web环境中的“请求”和“会话”作用域),可以使用更多的作用域

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的是应用程序组件注册的中心,同时集中应用程序组件的配置(程序模块不再需要读取诸如properties的配置文件)。这种设计的更多好处讨论详见的<J2EE设计开发编程指南>第4和第11章

Note 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.

相比诸如 BeanFactory 中查找的pull配置方式,通过setters或者构造方法,依赖注入的方式配置应用对象更好.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会从配置源(如X​​ML文件)中加载bena 定义,并使用{@code org.springframework.beans}包解析bean。然而,实现可以简单地返回Java代码直接新建的Java对象。这里没有限制bean 定义文件的格式: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.

对比{@link ListableBeanFactory}中的方法,如果这是一个{@linkHierarchicalBeanFactory},这个接口的全部实现都会查找父工厂.如果在这个工厂实例找不到bean,去直接父工厂查找。factory实例中的bean会覆盖父factory实例中的同名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的生命周期接口.全套的初始化方法,已经排序如下


package org.springframework.beans.factory;
 public interface BeanFactory {
 
     /**
      * 用于区分是否直接获取FactoryBean实例.
      * bean以&开头表示获取FactoryBean实例.否则获取created的实例.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.
      */
     String FACTORY_BEAN_PREFIX = "&";
 
     /**
      * 返回一个原型或者单例实例.
      * 抢单例,原型设计模式的饭碗
      * 可以根据别名查找,也可以去父容器实例查找
      */
     Object getBean(String name) throws BeansException;
 
     /**
      * 加个类型
      */
     <T> T getBean(String name, Class<T> requiredType) throws BeansException;
 
     /**
      * 根据类型获取bean实例.可以是接口或子类,但不能是{@code null}.
      * {@link ListableBeanFactory}也可以使用类型转化为name进行查找.更多bean集合的操作可以看
      * ListableBeanFactory和BeanFactoryUtils
      */
     <T> T getBean(Class<T> requiredType) throws BeansException;
 
     /**
      * 多了构造方法,工厂方法的参数
      */
     Object getBean(String name, Object... args) throws BeansException;
 
     /**
      * 判断是否包含bean(包括别名,父容器)
      * 陷阱出现:这边不管类是否抽象类,懒加载,是否在容器范围内,只要符合都返回true,所以这边true,不一定能从getBean获取实例
      */
     boolean containsBean(String name);
 
     /**
      * 是否单例
      */
     boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
 
     /**
      * 是否原型
      */
     boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
 
     /**
      * 是否有跟name匹配类型的bean
      */
     boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
 
     /**
      * 根据bean name获取类型
      */
     Class<?> getType(String name) throws NoSuchBeanDefinitionException;
 
     /**
      * 获取别名
      */
     String[] getAliases(String name);
 
 }

BeanFactory相关的2个重要类

🔥🔥ClassPathXmlApplicationContext
梳理了一下BeanFactory和ClassPathXmlApplicationContext的结构关系
image.png

BeanFactory---ListableBeanFactory--ApplicationContext---ConfigurableApplicationContext----AbstractApplicationContext---AbstractRefreshableApplicationContext---AbstractRefreshableConfigApplicationContext---AbstractXmlApplicationContext--ClassPathXmlApplicationContext

🔥🔥AnnotationConfigApplicationContext
使用AnnotationConfigApplicationContext可以实现基于Java的配置类加载Spring的应用上下文。避免使用application.xml进行配置。相比XML配置,更加便捷。

image.png

AnnotationConfigApplicationContext--GenericApplicationContext--AbstractApplicationContext---ConfigurableApplicationContext--ApplicationContext--ListableBeanFactory--BeanFactory

待续........

0

评论区