SpringApplication的createApplicationContext是用于创建ApplicationContext的策略方法。默认情况下,此方法将尊重任何显式设置的应用程序上下文类或工厂,然后再回退到合适的默认值。此方法返回的应用程序上下文是尚未刷新的。
private ApplicationContextFactory applicationContextFactory = ApplicationContextFactory.DEFAULT;
protected ConfigurableApplicationContext createApplicationContext() {
return this.applicationContextFactory.create(this.webApplicationType);
}
ApplicationContextFactory是用于创建SpringApplication使用的ConfigurableApplicationContext的策略接口(是一个函数式接口)。创建的上下文应该以其默认形式返回, SpringApplication负责配置和刷新上下文。
@FunctionalInterface
public interface ApplicationContextFactory {
/**
* 一个默认的ApplicationContextFactory实现,它将为WebApplicationType创建一个适当的上下文。
*/
ApplicationContextFactory DEFAULT = (webApplicationType) -> {
try {
switch (webApplicationType) {
case SERVLET:
return new AnnotationConfigServletWebServerApplicationContext();
case REACTIVE:
return new AnnotationConfigReactiveWebServerApplicationContext();
default:
return new AnnotationConfigApplicationContext();
}
}
catch (Exception ex) {
throw new IllegalStateException("Unable create a default ApplicationContext instance, "
+ "you may need a custom ApplicationContextFactory", ex);
}
};
/**
* 根据给定的webApplicationType创建SpringApplication的application context。
*/
ConfigurableApplicationContext create(WebApplicationType webApplicationType);
/**
* 创建一个ApplicationContextFactory,它将通过其主构造函数实例化给定的contextClass来创建上下文。
*/
static ApplicationContextFactory ofContextClass(Class<? extends ConfigurableApplicationContext> contextClass) {
return of(() -> BeanUtils.instantiateClass(contextClass));
}
/**
* 创建一个ApplicationContextFactory,它将通过调用给定的Supplier创建上下文。
*/
static ApplicationContextFactory of(Supplier<ConfigurableApplicationContext> supplier) {
return (webApplicationType) -> supplier.get();
}
}
由于我的应用引入了spring-boot-starter-webflux,所以在调用ApplicationContextFactory的create方法时传入的webApplicationType为REACTIVE,返回的是AnnotationConfigReactiveWebServerApplicationContext实例。
/**
* 使用steps检测应用程序启动阶段。
* 核心容器及其基础设施组件可以使用ApplicationStartup来标记应用程序启动期间的步骤,并收集有关执行上下文或其处理时间的数据。
* @since 5.3
*/
public interface ApplicationStartup {
/**
* 默认“无 *** 作” ApplicationStartup实现。
* 此变体旨在最小化开销,并且不记录数据。
*/
ApplicationStartup DEFAULT = new DefaultApplicationStartup();
/**
* 创建一个新步骤并标记它的开始。步骤名称描述当前 *** 作或阶段。这个技术名称应该是“.”命名空间,并且可以在应用程序启动期间重用于描述同一步骤的其他实例。
*/
StartupStep start(String name);
}
createApplicationContext方法执行完毕后,接着调用AnnotationConfigReactiveWebServerApplicationContext的setApplicationStartup方法,由于AnnotationConfigReactiveWebServerApplicationContext本身不重写该方法,所以调用的是GenericApplicationContext的setApplicationStartup方法。
GenericApplicationContext的setApplicationStartup方法:
private final DefaultListableBeanFactory beanFactory;
public void setApplicationStartup(ApplicationStartup applicationStartup) {
super.setApplicationStartup(applicationStartup);
this.beanFactory.setApplicationStartup(applicationStartup);
}
最终赋值给了AbstractApplicationContext的成员字段applicationStartup。
GenericApplicationContext的setApplicationStartup方法还有一段代码是调用其成员字段beanFactory的setApplicationStartup方法。
beanFactory是DefaultListableBeanFactory的实例。SpringApplication的createApplicationContext是通过创建GenericApplicationContext的无参构造方法创建AnnotationConfigReactiveWebServerApplicationContext的。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
DefaultListableBeanFactory是Spring的ConfigurableListableBeanFactory和BeanDefinitionRegistry接口的默认实现,是一个基于 bean 定义元数据的成熟 bean 工厂,可通过后处理器进行扩展。典型用法是在访问 bean 之前首先注册所有 bean 定义(可能从 bean 定义文件中读取,按名称查找Bean是本地bean定义表中的一种低成本 *** 作,它对预先解析的bean定义元数据对象进行 *** 作。)。
DefaultListableBeanFactory的层次性关系:
DefaultListableBeanFactory的无参构造器:
public DefaultListableBeanFactory() {
super();
}
AbstractAutowireCapableBeanFactory是实现默认bean创建的抽象bean工厂超类,具有RootBeanDefinition类指定的全部功能。除了 AbstractBeanFactory的createBean方法外,还实现了AutowireCapableBeanFactory接口。AbstractAutowireCapableBeanFactory提供 bean 创建(使用构造函数解析)、属性填充、连接(包括自动连接)和初始化。处理运行时bean引用、解析托管集合、调用初始化方法等。AbstractAutowireCapableBeanFactory支持自动装配构造函数、按名称的属性和按类型的属性(其子类要实现的主要模板方法是resolveDependency(DependencyDescriptor, String, Set, TypeConverter) ,用于按类型自动装配。如果工厂能够搜索其bean定义,匹配的 bean通常将通过这样的搜索来实现。对于其他工厂风格,可以实现简化的匹配算法)。AbstractAutowireCapableBeanFactory的无参构造器:
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
if (NativeDetector.inNativeImage()) {
this.instantiationStrategy = new SimpleInstantiationStrategy();
}
else {
this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
}
}
/** 创建bean实例的策略。 */
private InstantiationStrategy instantiationStrategy;
/**
* 在依赖检查和自动装配时忽略依赖接口,作为类对象集。默认情况下,仅忽略 BeanFactory 接口。
*/
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();
/**
* 忽略给定的依赖接口以进行自动装配。这通常被应用程序上下文用于注册以其他方式解析的依赖项,例如通过BeanFactoryAware的BeanFactory或通过ApplicationContextAware的ApplicationContext。
* 默认情况下,仅忽略 BeanFactoryAware 接口。要忽略其他类型,请为每种类型调用此方法。
*/
public void ignoreDependencyInterface(Class<?> ifc) {
this.ignoredDependencyInterfaces.add(ifc);
}
/**
* 用于检测 GraalVM 原生镜像环境的通用委托。
* 需要使用-H:+InlineBeforeAnalysis本机映像编译器标志,以允许在构建时删除代码。
*/
public abstract class NativeDetector {
// See https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java
private static final boolean imageCode = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
/**
* 如果在image构建的上下文中或在图像运行期间调用,则返回true ,否则返回false 。
*/
public static boolean inNativeImage() {
return imageCode;
}
}
AbstractBeanFactory是BeanFactory实现的抽象基类,提供ConfigurableBeanFactory SPI的全部功能。AbstractBeanFactory可以用作bean 工厂实现的基类,它从一些后端资源获取bean定义(其中bean定义访问是一项昂贵的 *** 作)。此类提供单例缓存(通过其基类DefaultSingletonBeanRegistry、单例/原型确定、FactoryBean处理、别名、合并子bean定义的bean定义和bean销毁(通过org.springframework.beans.factory.DisposableBean接口,自定义销毁方法)。此外,它可以通过实现org.springframework.beans.factory.HierarchicalBeanFactory接口来管理bean工厂层次结构(在未知bean的情况下委托给父级)。
子类实现的主要模板方法是getBeanDefinition和createBean,分别检索给定bean名称的bean定义和为给定bean定义创建 bean 实例。这些 *** 作的默认实现可以在DefaultListableBeanFactory和AbstractAutowireCapableBeanFactory中找到。AbstractBeanFactory的无参构造器:
public AbstractBeanFactory() {
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)