Spring 源码分析(二)--- IOC 根类结构图

一、引言

根据上一篇Spring 源码分析(一)— IOC demo 可知,采用 xml 配置方式配置 Bean 的时候,入口类是 ClassPathXmlApplicationContext,就从 ClassPathXmlApplicationContext 入手,来进行分析。

二、ClassPathXmlApplicationContext 类图分析

如下,是 ClassPathXmlApplicationContext 类的继承关系图,通过分析该继承关系来一步步解析 Spring IOC 源码。
ClassPathXmlApplicationContext 的类关系图

由类关系图可知,ClassPathXmlApplicationContext 最顶层父类接口有七个:

  • BeanFactory
  • Aware
  • LifeCycle
  • InitializingBean
  • ResourceLoader
  • ApplicationEventPublisher
  • AutoCloseable

2.1. BeanFactory

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

BeanFactory 的 Implementation 如下:
BeanFactory 的实现类关系图
ListableBeanFactory

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

HierarchicalBeanFactory

/**
 * 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 {
    
    

StaticListableBeanFactory

/**
 * 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 {
    
    

StubBeanFactory

/**
 * 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 {
    
    

ApplicationContext

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

WebApplicationContext

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

ConfigurableApplicationContext

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

AbstractApplicationContext

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

AbstractRefreshableApplicationContext

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

AbstractRefreshableConfigApplicationContext

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

AbstractXmlApplicationContext

/** 
 * 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 {
    
    

AbstractRefreshableWebApplicationContext

/**
 * 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 {
    
    

XmlWebApplicationContext

/**
 * 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 {
    
    

GroovyWebApplicationContext

/**
 * 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 {
    
    

GenericApplicationContext

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

GenericXmlApplicationContext

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

GenericGroovyApplicationContext

/**
 * 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 {
    
    

ConfigurableWebApplicationContext

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

StaticApplicationContext

/**
 * 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. Aware

1.Spring 的依赖注入最大亮点就是所有的 Bean 对 Spring 容器的存在是没有意识的;
2.但是在实际项目中,我们不可避免的要用到 Spring 容器本身提供的资源,这时候要让 Bean 主动意识到 Spring 容器的存在,才能调用 Spring 所提供的资源,这就是 Spring Aware;

2.3. LifeCycle

1.定义启动/停止生命周期控制方法的通用接口;

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

1.Spring 提供的拓展性接口,InitializingBean 接口为 Bean 提供了属性初始化后的处理方法,它只有一个 afterPropertiesSet() 方法,凡是继承该接口的类,在 Bean 的属性初始化后都会执行该方法,进行其总体配置和最终初始化验证;

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

1.用于加载资源(例如,类路径或文件系统资源)的策略接口;

1.Spring 中整合了获取资源的工具,就是使用 Resource 接口。此接口是 Spring 为了统一读取诸如本地文件、classpath 项目路径下的文件、url 互联网上的文件等不同类型渠道的资源,封装隐藏如打开流、关闭流、报错处理等大量重复模板代码,而专程设计提供的接口类。
2.而 Spring 框架为了更方便的获取资源,尽量弱化程序员对各个 Resource 接口实现类的感知与分辨,降低学习与使用成本,定义了另一个接口,就是: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. ApplicationEventPublisher

1.封装事件发布功能的接口;
2.函数式接口;

@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. AutoCloseable

1.当一个资源类实现了该接口 close 方法,在使用 try-with-resources 语法创建的资源抛出异常后,JVM 会自动调用 close 方法进行资源释放;当没有抛出异常正常退出 try 代码块时也会自动调用 close 方法。像数据库链接类 Connection,io 类 InputStream 或 OutputStream 都直接或者间接实现了该接口;

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;
}

猜你喜欢

转载自blog.csdn.net/weixin_39651041/article/details/129674784
今日推荐