1、ApplicationContextInitializer初始化器解析

编程

1.3、初始化器解析

1) 在上下文刷新即refresh方法前调用

2) 用来编码设置一些属性变量,通常用在web环境中

3) 可以通过order接口进行排序

1.4、 添加原理分析

1) 定义在spring.factories文件中被SpringFactoriesLoader发现注册

2) SpringApplication初始化完毕后手动添加

3) 定义成环境变量被DelegatingApplicationContextInitializer发现注册

1.4.1、方式1分析

方式1)代码分析:定义在spring.factories文件中被SpringFactoriesLoader发现注册

@SpringBootApplication

public class SpringbootApplication {

public static void main(String[] args) {

SpringApplication.run(SpringbootApplication.class, args);

}

}

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {

return run(new Class<?>[] { primarySource }, args);

}

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {

return new SpringApplication(primarySources).run(args);

}

public SpringApplication(Class<?>... primarySources) {

this(null, primarySources);

}

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {

this.resourceLoader = resourceLoader;

Assert.notNull(primarySources, "PrimarySources must not be null");

this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));

this.webApplicationType = WebApplicationType.deduceFromClasspath();

// 到这一步从spring.factories中加载ApplicationContextInitializer.class的实现类

setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class));

setListeners((Collection)getSpringFactoriesInstances(ApplicationListener.class));

this.mainApplicationClass = deduceMainApplicationClass();

}

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {

return getSpringFactoriesInstances(type, new Class<?>[] {});

}

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {

ClassLoader classLoader = getClassLoader();

// Use names and ensure unique to protect against duplicates

// 1) 从spring.factories中加载ApplicationContextInitializer.class的实现类

Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

// 2) 实例化步骤1中得到的实现类

List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);

// 3) 根据order注解进行排序

AnnotationAwareOrderComparator.sort(instances);

return instances;

}

// 1) 从spring.factories中加载ApplicationContextInitializer.class的实现类

Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {

// org.springframework.context.ApplicationContextInitializer

String factoryClassName = factoryClass.getName();

// 获得一个Map,map形如<key,List<String>>形式,后面getOrDefault是获取

// org.springframework.context.ApplicationContextInitializer对应的实现类集合

return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());

}

// 带缓存功能,从各个jar包的META-INF/spring.factories文件中加载实现类,一个key可能包含多个实现

private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {

MultiValueMap<String, String> result = cache.get(classLoader);

if (result != null) {

// 缓存中有直接返回

return result;

}

try {

// FACTORIES_RESOURCE_LOCATION值是META-INF/spring.factories

Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :

ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));

result = new LinkedMultiValueMap<>();

while (urls.hasMoreElements()) {

URL url = urls.nextElement();

UrlResource resource = new UrlResource(url);

Properties properties = PropertiesLoaderUtils.loadProperties(resource);

for (Map.Entry<?, ?> entry : properties.entrySet()) {

// 获取key

String factoryClassName = ((String) entry.getKey()).trim();

// 将value逗号分隔,获得各个具体的实现类

for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {

// 放入result中

result.add(factoryClassName, factoryName.trim());

}

}

}

cache.put(classLoader, result);

// 返回的result见下图

return result;

}

}

// 2) 实例化步骤1中得到的实现类

List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);

private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader,

Object[] args, Set<String> names) {

List<T> instances = new ArrayList<>(names.size());

for (String name : names) {

try {

Class<?> instanceClass = ClassUtils.forName(name, classLoader);

// 判断instanceClass是否是ApplicationContextInitializer的实现类

Assert.isAssignable(type, instanceClass);

Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);

T instance = (T) BeanUtils.instantiateClass(constructor, args);

instances.add(instance);

}

}

return instances;

}

// 3) 根据order注解进行排序

AnnotationAwareOrderComparator.sort(instances);

public static final AnnotationAwareOrderComparator INSTANCE = new AnnotationAwareOrderComparator();

public static void sort(List<?> list) {

if (list.size() > 1) {

list.sort(INSTANCE);

}

}

1.4.2、方式2分析

方式2)代码分析:手动添加

@SpringBootApplication

public class SpringbootApplication {

public static void main(String[] args) {

SpringApplication springApplication = new SpringApplication(SpringbootApplication.class);

springApplication.addInitializers(new SecondInitializer());

springApplication.run(args);

}

}

public void addInitializers(ApplicationContextInitializer<?>... initializers) {

// 方式1最终也是放入到了SpringApplication的initializers集合中

this.initializers.addAll(Arrays.asList(initializers));

}

1.4.3、方式3分析

方式3)代码分析:在application.properties中配置,通过DelegatingApplicationContextInitializer注入

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {

ClassLoader classLoader = getClassLoader();

// 这边加载之后默认有7个实现类,有一个是DelegatingApplicationContextInitializer

Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);

// 排完序后见下图,发现DelegatingApplicationContextInitializer在最前

AnnotationAwareOrderComparator.sort(instances);

return instances;

}

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {

// 方式1中分析的是SpringApplicatin的构造函数,构造函数完了之后已经加载了spring.factories的

// class到SpringApplication的initializers集合中,接着运行run函数

return new SpringApplication(primarySources).run(args);

}

// 核心代码,删除了部分代码,只分析与此有关的步骤

public ConfigurableApplicationContext run(String... args) {

try {

context = createApplicationContext();

// 走这一步

prepareContext(context, environment, listeners, applicationArguments, printedBanner);

refreshContext(context);

afterRefresh(context, applicationArguments);

}

return context;

}

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,

SpringApplicationRunListeners listeners,

ApplicationArguments applicationArguments,

Banner printedBanner) {

context.setEnvironment(environment);

postProcessApplicationContext(context);

// 走这一步,调用各个initializers的initialize方法

applyInitializers(context);

// 删除部分代码

}

protected void applyInitializers(ConfigurableApplicationContext context) {

// 遍历每个initializers,调用其initialize方法

for (ApplicationContextInitializer initializer : getInitializers()) {

Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),

ApplicationContextInitializer.class);

Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");

// 调用initialize方法,第一个调用的就是DelegatingApplicationContextInitializer

initializer.initialize(context);

}

}

// DelegatingApplicationContextInitializer的initialize方法

public void initialize(ConfigurableApplicationContext context) {

ConfigurableEnvironment environment = context.getEnvironment();

List<Class<?>> initializerClasses = getInitializerClasses(environment);

if (!initializerClasses.isEmpty()) {

applyInitializerClasses(context, initializerClasses);

}

}

private List<Class<?>> getInitializerClasses(ConfigurableEnvironment env) {

// PROPERTY_NAME = "context.initializer.classes";

// classNames这里是com.lwh.springboot.initializer.ThirdInitializer

String classNames = env.getProperty(PROPERTY_NAME);

List<Class<?>> classes = new ArrayList<>();

if (StringUtils.hasLength(classNames)) {

for (String className : StringUtils.tokenizeToStringArray(classNames, ",")) {

classes.add(getInitializerClass(className));

}

}

return classes;

}

private void applyInitializerClasses(ConfigurableApplicationContext context,

List<Class<?>> initializerClasses) {

Class<?> contextClass = context.getClass();

List<ApplicationContextInitializer<?>> initializers = new ArrayList<>();

// 实例化Initializer对象

for (Class<?> initializerClass : initializerClasses) {

initializers.add(instantiateInitializer(contextClass, initializerClass));

}

// 调用initialize方法

applyInitializers(context, initializers);

}

以上是 1、ApplicationContextInitializer初始化器解析 的全部内容, 来源链接: utcz.com/z/513537.html

回到顶部