Análisis del código fuente de Spring (2) --- Diagrama de estructura de clases raíz del COI

I. Introducción

De acuerdo con el análisis anterior del código fuente de Spring (1): demostración de IOC , al configurar beans usando la configuración xml, la clase de entrada es ClassPathXmlApplicationContext, por lo que comenzamos con ClassPathXmlApplicationContext para el análisis.

2. Análisis del diagrama de clases ClassPathXmlApplicationContext

El siguiente es el diagrama de relación de herencia de la clase ClassPathXmlApplicationContext: al analizar la relación de herencia, el código fuente de Spring IOC se puede analizar paso a paso.
Diagrama de clases de ClassPathXmlApplicationContext

Como se puede ver en el diagrama de relación de clases, hay siete interfaces de clase principal de nivel superior de ClassPathXmlApplicationContext:

  • fábrica de frijoles
  • Consciente
  • Ciclo vital
  • InicializandoBean
  • Cargador de recursos
  • AplicaciónEventPublisher
  • Autocerrable

2.1. fábrica de frijoles

/**
 * 1. BeanFactory 是访问 Spring Bean 容器的根接口;
 * 2. 定义根据 Bean name 获取 Bean 的接口;
 */
public interface BeanFactory {
    
    

La implementación de BeanFactory es la siguiente:
Diagrama de clases de implementación de BeanFactory
ListableBeanFactory

/**
 * 1. 扩展 BeanFactory 接口,可以枚举其所有的 Bean 实例;
 * 2. 预加载所有 Bean 定义的 BeanFactory 实现(例如基于 XML 的工厂)可以实现此接口;
 */
public interface ListableBeanFactory extends BeanFactory {
    
    

JerárquicoBeanFactory

/**
 * 1. 扩展 BeanFactory 的接口,实现了 Bean 工厂的分层,扩展了工厂分层的功能。
 */
public interface HierarchicalBeanFactory extends BeanFactory {
    
    

AutowireCapableBeanFactory

/**
 * 1. 扩展 BeanFactory 接口,使有能力自动装配 ApplicationContext 管理之外的 Bean;
 * 2. ApplicationContext 接口没有实现 AutowireCapableBeanFactory 接口,因为应用代码很少用到此功能,如果需要的话,可以调用 ApplicationContext 的 getAutowireCapableBeanFactory 方法,来获取此接口的实例。
 */
public interface AutowireCapableBeanFactory extends BeanFactory {
    
    

SimpleJndiBeanFactory

/**
 * 1. 基于 JNDI 的 Spring BeanFactory 接口的简单实现;
 * 2. 不支持枚举 bean 定义,因此不实现 org.springframework.beans.factory.ListableBeanFactory 接口。
 */
public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFactory {
    
    

EstáticoListableBeanFactory

/**
 * 1. BeanFactory 的静态实现,它允许以编程方式注册现有的单例实例。
 * 2. 不支持原型 Bean 或别名。
 * 3. 作为 ListableBeanFactory 接口的简单实现的示例,管理现有的 Bean 实例,而不是基于 Bean 定义创建新的实例,并且不实现任何扩展的 SPI 接口(如 org.springframework.beans.factory.config.ConfigurableBeanFactory)。
 * 4. 对于基于 Bean 定义的成熟工厂,请查看 DefaultListableBeanFactory。
 */
public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFactory {
    
    

StubBeanFábrica

/**
 * 1. StaticListableBeanFactory 的扩展,它实现了 AutowireCapableBeanFactory,以便允许 ApplicationContextAware 单例的 Bean 初始化;
 */
private class StubBeanFactory extends StaticListableBeanFactory implements AutowireCapableBeanFactory {
    
    

ConfigurableListableBeanFactory

/**
 * 1. 大多数可列出的 Bean 工厂要实现的配置接口。除了 ConfigurableBeanFactory 之外,它还提供了分析和修改 Bean 定义以及预实例化单例的工具;
 * 2. BeanFactory 的这个子接口不适合在普通应用程序代码中使用:对于典型用例,请坚持使用 org.springframework.beans.factory.BeanFactory 或 ListableBeanFactory;
 * 3. 此接口只是为了允许框架内部即插即用,即使需要访问 Bean 工厂配置方法也是如此。
 */
public interface ConfigurableListableBeanFactory
		extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
    
    

Contexto de aplicación

/**
 * 1. 为应用程序提供配置的中央接口;
 * 2. 在应用程序运行时是只读的,可以通过重新加载,来实现支持此功能;
 * 3. 主要是各种属性的 get 方法;
 */
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    
    

Contexto de aplicación web

/**
 * 1. 专门为<font color="red"> Web 应用程序</font>提供配置的接口;
 * 2. 从 WebApplicationContext 中可以获得 ServletContext 的引用;会定义一个众所周知的应用程序属性名称,根上下文必须在引导过程中绑定到该名称;
 * 3. 与 ApplicationContext 一样,WebApplicationContext 也是分层的。每个应用程序都有一个根上下文,而应用程序中的每个 servlet(包括 MVC 框架中的调度程序 servlet)都有自己的子上下文;**
 */
public interface WebApplicationContext extends ApplicationContext {
    
    

Contexto de aplicación configurable

/**
 * 1. SPI 接口将被大多数而非所有的应用程序上下文实现;
 * 2. 此处封装了配置和生命周期方法,以避免它们对 ApplicationContext 客户端代码显而易见。当前方法应仅由启动和关闭代码使用;
 * 3. 主要是各种属性的配置;
 */
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
    
    

ResumenAplicaciónContexto

/**
 * 1. ApplicationContext 的抽象实现;
 * 2. 不强制要求用于配置的存储类型;只是实现通用上下文功能;
 * 3. 使用模板方法设计模式,需要具体的子类来实现抽象方法;
 */
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
    
    

ResumenRefreshableApplicationContext

/**
 * 1. ApplicationContext 实现的基类;
 * 2. 主要是和容器的刷新与创建有关,调用 refreshBeanFactory 方法完成 applicationContext.xml 的解析操作,完成容器的初始化操作;
 */
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
    
    

ResumenRefreshableConfigApplicationContext

/**
 * 1.用于添加对指定配置位置的通用处理;直白一点就是加载容器刷新时的配置文件的通用操作;
 * 2.该类的两个子类,都是基于 xml 配置文件,将会有各自的定制的读取配置文件操作,所以该类提供的是读取配置文件通用操作,提供拓展点;
 */
public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
		implements BeanNameAware, InitializingBean {
    
    

ResumenXmlApplicationContext

/** 
 * 1. 从包含 Bean 定义的 XML 文件加载 Bean 的方便基类;使用 XmlBeanDefinitionReader 进行解析 XML;
 * 2. 子类只需要实现 getConfigResources 和/或 getConfigLocations 方法;
 * 3. 它们可能会覆盖 getResourceByPath 钩子以以特定于环境的方式解释相对路径,和/或 getResourcePatternResolver 以扩展模式解析;
 */
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
    
    

FileSystemXmlApplicationContext

/**
 * 1. 独立的 XML 应用程序上下文,从文件系统或 URL 获取上下文定义文件,将纯路径解释为相对文件系统位置(例如“mydir/myfile.txt”)。适用于测试工具以及独立环境;
 * 2. 没有盘符的是项目工作目录,即项目的根目录;
 * 3. 有盘符表示的是文件绝对路径, file: 前缀可加可不加;
 * 4. 也可以使用 classpath 路径,如果要使用,需要前缀 classpath: ;
 */
public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {
    
    

ClassPathXmlApplicationContext

/**
 * 1. 从类路径中获取上下文定义文件,将普通路径解释为包含包路径的类路径资源名称;
 * 2. 从 classpath 路径下加载 xml 配置文件;
 * 3. 默认是指项目的 classpath 路径下面, classpath: 前缀是可加可不加的;
 * 4. 如果要使用绝对路径,需要加上 file: 前缀,表示这是绝对路径;
 */
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
    
    

ResumenRefreshableWebApplicationContext

/**
 * 1. AbstractRefreshableApplicationContext 的子类,AbstractRefreshableApplicationContext 的 Web 环境;
 */
public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableConfigApplicationContext
		implements ConfigurableWebApplicationContext, ThemeSource {
    
    

AnnotationConfigWebApplicationContext

/**
 * 1. org.springframework.web.context.WebApplicationContext 实现,处理 @Configuration @Component 以及使用jakarta.inject 注解的 JSR-330 兼容类;
 * 2. 允许逐个注册类(将类名指定为配置位置)以及通过类路径扫描(将基本包指定为配置位置);
 * 3. 这实质上相当于 Web 环境的 org.springframework.context.annotation.AnnotationConfigApplicationContext;
 */
public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWebApplicationContext
		implements AnnotationConfigRegistry {
    
    

ContextodeAplicaciónWebXml

/**
 * 1. org.springframework.web.context.WebApplicationContext 实现,它从 XML 文档中获取其配置,由XmlBeanDefinitionReader 来解析;
 * 2. 这实质上相当于 Web 环境的 org.springframework.context.support.GenericXmlApplicationContext;
 * 3. 根 context 默认从 /WEB-INF/applicationContext.xml 获取配置文件;
 */
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
    
    

Contexto de aplicación GroovyWeb

/**
 * 1. org.springframework.web.context.WebApplicationContext 实现,它从 Groovy 文档中获取其配置,由 org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader 来解析;
 * 2. 这实质上相当于 Web 环境的 org.springframework.context.support.GenericGroovyApplicationContex;
 * 3. 根 context 默认从 /WEB-INF/applicationContext.groovy 获取配置文件;
 */
public class GroovyWebApplicationContext extends AbstractRefreshableWebApplicationContext implements GroovyObject {
    
    

Contexto de aplicación genérica

/**
 * 1.通用的 ApplicationContext 实现;采用混合方式(XML、注解等)处理 bean 的定义,而不是采用特定的 bean 定义方式来创建bean;
 * 2.内部有一个 DefaultListableBeanFactory 实例;实现 BeanDefinitionRegistry 接口,以便允许对其应用任何 Bean 定义读取器;
 */
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
    
    

Contexto de aplicación Xml genérico

/**
 * 1. 具有内置 XML 支持的便捷应用程序上下文;
 * 2. 是 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext 的灵活替代方案,可通过 setter 进行配置,最终 refresh() 调用激活上下文;
 */
public class GenericXmlApplicationContext extends GenericApplicationContext {
    
    

Contexto de aplicación genérico Groovy

/**
 * 1. org.springframework.context.ApplicationContext 实现,它扩展了 GenericApplicationContext 并实现了 GroovyObject,以便可以使用 Groovy 语法代替 getBean 来检索 bean;
 */
public class GenericGroovyApplicationContext extends GenericApplicationContext implements GroovyObject {
    
    

AnnotationConfigApplicationContext

/**
 * 1. 注解配置的 ApplicationContext 实现;
 * 2. 处理 @Configuration,包括使用 jakarta.inject 注解的纯 @Component 类型和符合 JSR-330 的类;
 */
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
    
    

Contexto de aplicación web configurable

/**
 * 1. ConfigurableApplicationContext 的 Web 实现;
 */
public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {
    
    

Contexto de aplicación estática

/**
 * 1. ApplicationContext 实现,它支持以编程方式注册 bean 和消息,而不是从外部配置源读取 Bean 定义。主要用于测试;
 */
public class StaticApplicationContext extends GenericApplicationContext {
    
    

StubWebApplicationContext

/**
 * 1. 接受对象实例注册的 Stub WebApplicationContext;
 */
class StubWebApplicationContext implements WebApplicationContext {
    
    

ConfigurableBeanFactory

/**
 * 1.大多数 bean factories 要实现的配置接口。提供用于配置 Bean 工厂的工具,以及 BeanFactory 接口中的 Bean 工厂客户端方法。
 * 2.此接口不适用于普通应用程序代码:坚持使用 BeanFactory 或 org.springframework.beans.factory.ListableBeanFactory 以满足典型需求;
 * 3.此扩展接口只是为了允许框架内部即插即用和对 Bean 工厂配置方法的特殊访问;
 */
public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFactory

2.2. Consciente

1. Lo más destacado de la inyección de dependencia de Spring es que todos los beans desconocen la existencia del contenedor Spring;
2. Sin embargo, en proyectos reales, inevitablemente utilizaremos los recursos proporcionados por el propio contenedor Spring. En este momento, los beans debe tomar la iniciativa Solo cuando conozca la existencia del contenedor Spring podrá llamar a los recursos proporcionados por Spring, esto es Spring Aware;

2.3. Ciclo vital

1. Definir una interfaz común para iniciar/detener los métodos de control del ciclo de vida;

public interface Lifecycle {
    
    

	/** 
	 * Start this component. 
	 */
	void start();

	/** 
	 * Stop this component, typically in a synchronous fashion, such that the component is
	 * fully stopped upon return of this method.
	 */
	void stop();

	/**
	 * Check whether this component is currently running.
	 */
	boolean isRunning();

}

2.4. InicializandoBean

1. La interfaz extensible proporcionada por Spring. La interfaz InitializingBean proporciona a Bean un método de procesamiento después de la inicialización de la propiedad. Tiene solo un método afterPropertiesSet(). Cualquier clase que herede esta interfaz ejecutará este método después de que se inicialicen las propiedades del Bean y realizará otras procesamiento Configuración general y verificación de inicialización final;

public interface InitializingBean {
    
    

	/**
	 * Invoked by the containing {@code BeanFactory} after it has set all bean properties
	 * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
	 * <p>This method allows the bean instance to perform validation of its overall
	 * configuration and final initialization when all bean properties have been set.
	 * @throws Exception in the event of misconfiguration (such as failure to set an
	 * essential property) or if initialization fails for any other reason
	 */
	void afterPropertiesSet() throws Exception;

}

2.5. Cargador de recursos

1. Una interfaz de política para cargar recursos (por ejemplo, classpath o recursos del sistema de archivos);

1. Spring integra herramientas para obtener recursos, que consiste en utilizar la interfaz de recursos. Esta interfaz está especialmente diseñada por Spring para leer de manera uniforme recursos de diferentes tipos de canales, como archivos locales, archivos en la ruta del proyecto classpath y archivos URL en Internet, y encapsular y ocultar una gran cantidad de códigos de plantilla repetitivos, como secuencias de apertura. , cierre de flujos y manejo de errores. Diseñe la clase de interfaz proporcionada.
2. Para obtener recursos de manera más conveniente, el marco Spring intenta debilitar la percepción y discriminación de los programadores de cada clase de implementación de la interfaz de recursos y reducir los costos de aprendizaje y uso, y define otra interfaz, a saber: la interfaz ResourceLoader.

public interface ResourceLoader {
    
    

	/** Pseudo URL prefix for loading from the class path: "classpath:". */
	String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
	
	/**
	 * Return a {@code Resource} handle for the specified resource location.
	 */
	Resource getResource(String location);

	/**
	 * Expose the {@link ClassLoader} used by this {@code ResourceLoader}.
	 */
	@Nullable
	ClassLoader getClassLoader();
}

2.6. AplicaciónEventPublisher

1. Una interfaz que encapsula la función de publicación de eventos;
2. Interfaz funcional;

@FunctionalInterface
public interface ApplicationEventPublisher {
    
    

	/**
	 * Notify all <strong>matching</strong> listeners registered with this
	 * application of an application event. Events may be framework events
	 * (such as ContextRefreshedEvent) or application-specific events.
	 */
	default void publishEvent(ApplicationEvent event) {
    
    
		publishEvent((Object) event);
	}

	/**
	 * Notify all <strong>matching</strong> listeners registered with this
	 * application of an event.
	 */
	void publishEvent(Object event);
}

2.7. Autocerrable

1. Cuando una clase de recurso implementa el método de cierre de esta interfaz, después de que el recurso creado usando la sintaxis de prueba con recursos arroja una excepción, la JVM llamará automáticamente al método de cierre para liberar el recurso; cuando no se lanza ninguna excepción, el método de cierre de esta interfaz El bloque de código de prueba saldrá normalmente y el método de cierre también se llamará automáticamente. Al igual que la clase de conexión de base de datos Connection, la clase io InputStream o OutputStream implementan directa o indirectamente esta interfaz;

public interface AutoCloseable {
    
    
    /**
     * Closes this resource, relinquishing any underlying resources.
     * This method is invoked automatically on objects managed by the
     * {@code try}-with-resources statement.
     */
    void close() throws Exception;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_39651041/article/details/129674784
Recomendado
Clasificación