Spring Boot原理(一):初期化

4592 ワード

spring bootの起動には2ステップ、1.SprigAplicationオブジェクトの生成、2.runメソッドの呼び出しが含まれています.Spring独自のステップとSpring Boot独自のステップが含まれています.一連の文章は一歩ずつ解析されます.能力は限られています.問題があれば指摘してください.本論文は第一歩の過程を説明し、次の章はrunメソッドを呼び出すと説明する.
1.起動コード
SpringApplication.run(DemoApplication.class, args);
2.SprigAplicationオブジェクトを生成する
public SpringApplication(Object... sources) {
   initialize(sources);
}
public SpringApplication(ResourceLoader resourceLoader, Object... sources) {
   this.resourceLoader = resourceLoader;
   initialize(sources);
}
i.Spring Applicationの構造関数は2つあります.sourcesは起動するクラスで、一般的にrunメソッドの類名を呼びます.reourcene LoaderはSpringでリソースファイルをロードするクラスです.デフォルトではDefaultResource Loader類です.web環境ではServletContextResource Loaderもあります.
ii.initialize-初期化は5ステップに分けられ、主に各種のプライベート変数の割り当てである.
@SuppressWarnings({ "unchecked", "rawtypes" })
private void initialize(Object[] sources) {
  if (sources != null && sources.length > 0) {
     this.sources.addAll(Arrays.asList(sources));
  }
  this.webEnvironment = deduceWebEnvironment();
  setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
  setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
  this.mainApplicationClass = deduceMainApplicationClass();
}
a.sourcesをSet sourcesに加入する.
b.現在許可されている環境がweb環境かどうかを判断し、各種のロードされているクラスの中に「javax.servlet.Servlet」があるかどうかを判断し、「org.springframe ork.web.com.web.com.com.com.cn figrable WebApple Context」で両者がウェブ環境と表示されているかどうかを判断しても初期化された後に、runメソッドが呼び出される前にEntroment.Entroment.Entroment.Envimen
c.デフォルトのAppliation Contect tInitializerを生成する親類Initializer.
d.デフォルトのApple Listenerを生成する父親類listener.
e.判読main関数はその種類の中にありますので、SpringBootの工程の中では一番いいのは一つのmain方法だけです.StockTrace Elementを使って、スタックの情報を呼び出すことができます.
3.解析spring.factoresはロードが必要なInitializerとlistenerを取得します.
第2ステップcとdのステップではデフォルトInitializerとlistenerをロードし、すべてのjarパケットの中のMETA-INF/spring.factoresを判断し、さらにAppliation Contect InitiazerまたはAppliation Listenerの親類を取り出して実例化する必要がある.
private  Collection extends T> getSpringFactoriesInstances(Class type,
      Class>[] parameterTypes, Object... args) {
   ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

   // Use names and ensure unique to protect against duplicates
   Set names = new LinkedHashSet(
         SpringFactoriesLoader.loadFactoryNames(type, classLoader));
   List instances = new ArrayList(names.size());

   // Create instances from the names
   for (String name : names) {
      try {
         Class> instanceClass = ClassUtils.forName(name, classLoader);
         Assert.isAssignable(type, instanceClass);
         Constructor> constructor = instanceClass.getConstructor(parameterTypes);
         T instance = (T) constructor.newInstance(args);
         instances.add(instance);
      }
      catch (Throwable ex) {
         throw new IllegalArgumentException("Cannot instantiate " + type + " : "
               + name, ex);
      }
   }

   AnnotationAwareOrderComparator.sort(instances);
   return instances;
}
public static List loadFactoryNames(Class> factoryClass, ClassLoader classLoader) {
  String factoryClassName = factoryClass.getName();
  try {
     Enumeration urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
           ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
     List result = new ArrayList();
     while (urls.hasMoreElements()) {
        URL url = urls.nextElement();
        Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
        String factoryClassNames = properties.getProperty(factoryClassName);
        result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
     }
     return result;
  }
  catch (IOException ex) {
     throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
           "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
  }
}    
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
自分のInitializerとlistenerをロードしたいならば、spring.factoresに追加するか、addInitiazers addListenersによって増加することができます.
4.後記
ここで、Spring Bootの生成対象は終了しました.その後はウェブ環境、カスタムInitializerとlistenerなどの独特な構成をセットして、最後にrunメソッドを呼び出して、bean初期化構造、configロードなどを行います.