1. 程式人生 > >Springboot內建ApplicationContextInitializer--DelegatingApplicationContextInitializer

Springboot內建ApplicationContextInitializer--DelegatingApplicationContextInitializer

原始碼分析

本文程式碼基於 Springboot 2.1.0

執行環境屬性"context.initializer.classes"指定的初始化器,這裡其實是給springboot應用程式使用者提供了一個機會指定自己實現的ApplicationContextInitializer對應用程式做一些初始化工作。

package org.springframework.boot.context.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.
beans.BeanUtils; import org.springframework.context.ApplicationContextException; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.GenericTypeResolver; import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; /** * ApplicationContextInitializer that delegates to other initializers that are * specified under a "context.initializer.classes" environment property. * * 執行環境屬性"context.initializer.classes"指定的初始化器 * @author Dave Syer * @author Phillip Webb */
public class DelegatingApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered { // NOTE: Similar to org.springframework.web.context.ContextLoader private static final String PROPERTY_NAME = "context.initializer.classes"; private int order = 0; @Override public void initialize(ConfigurableApplicationContext context) { ConfigurableEnvironment environment = context.getEnvironment(); // 從環境屬性context.initializer.classes分析出各個ApplicationContextInitializer實現類 // 並應用它們,也就是例項化它們並呼叫它們的initialize(context)方法 List<Class<?>> initializerClasses = getInitializerClasses(environment); if (!initializerClasses.isEmpty()) { applyInitializerClasses(context, initializerClasses); } } private List<Class<?>> getInitializerClasses(ConfigurableEnvironment env) { // 環境屬性context.initializer.classes是一個字串,以逗號分割, // 分隔開的每一部分是一個類的全名稱,並且該類應該是一個ApplicationContextInitializer實現類 String classNames = env.getProperty(PROPERTY_NAME); List<Class<?>> classes = new ArrayList<>(); if (StringUtils.hasLength(classNames)) { for (String className : StringUtils.tokenizeToStringArray(classNames, ",")) { // 獲取每一個類名稱,分析其對對應的ApplicationContextInitializer實現類, // 如果某個類名稱字串並不對應classpath上的某個類,或者不是一個ApplicationContextInitializer // 實現類,這裡會丟擲ClassNotFoundException異常 classes.add(getInitializerClass(className)); } } return classes; } private Class<?> getInitializerClass(String className) throws LinkageError { try { Class<?> initializerClass = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader()); Assert.isAssignable(ApplicationContextInitializer.class, initializerClass); return initializerClass; } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load context initializer class [" + className + "]", ex); } } private void applyInitializerClasses(ConfigurableApplicationContext context, List<Class<?>> initializerClasses) { Class<?> contextClass = context.getClass(); List<ApplicationContextInitializer<?>> initializers = new ArrayList<>(); for (Class<?> initializerClass : initializerClasses) { initializers.add(instantiateInitializer(contextClass, initializerClass)); } applyInitializers(context, initializers); } private ApplicationContextInitializer<?> instantiateInitializer(Class<?> contextClass, Class<?> initializerClass) { Class<?> requireContextClass = GenericTypeResolver.resolveTypeArgument( initializerClass, ApplicationContextInitializer.class); Assert.isAssignable(requireContextClass, contextClass, String.format( "Could not add context initializer [%s]" + " as its generic parameter [%s] is not assignable " + "from the type of application context used by this " + "context loader [%s]: ", initializerClass.getName(), requireContextClass.getName(), contextClass.getName())); return (ApplicationContextInitializer<?>) BeanUtils .instantiateClass(initializerClass); } @SuppressWarnings({ "unchecked", "rawtypes" }) private void applyInitializers(ConfigurableApplicationContext context, List<ApplicationContextInitializer<?>> initializers) { // 應用這些ApplicationContextInitializer之前先對他們進行排序 initializers.sort(new AnnotationAwareOrderComparator()); for (ApplicationContextInitializer initializer : initializers) { initializer.initialize(context); } } public void setOrder(int order) { this.order = order; } @Override public int getOrder() { return this.order; } }

相關文章

Springboot 內建ApplicationContextInitializer