分析Springbootアプリケーションの起動原理

非常に魅力的な特徴で春ブーツ内のJAR /戦争というパッケージに直接適用することができ、このjar /戦争を直接起動することができ、追加の設定Webサーバを必要としません。

疑い

  • 春ブーツはどのように開始するには?
  • どのように春が構築された埋め込みTomcatの作品を起動しますか?静的ファイル、JSP、どのようにWebページのテンプレートをロードするには?

単一のjarパッケージ、春のブート起動モードとしてパッケージ化すると

Mavenのパッケージの後、2つのJARファイルを生成します。

demo-0.0.1-SNAPSHOT.jar
demo-0.0.1-SNAPSHOT.jar.original

ここでデモ-0.0.1-SNAPSHOT.jar.originalは、デフォルトのMavenジャー・プラグイン生成されたパケットです。デモ-0.0.1-SNAPSHOT.jarにプラグインは、アプリケーションに依存し、そして春ブーツ関連するクラスが含まれている春ブーツMAVEN生成されたjarファイルパッケージです。

春のブートパッケージのディレクトリ構造で見てみましょう:

├── META-INF
│   ├── MANIFEST.MF
├── application.properties
├── com
│   └── example
│       └── SpringBootDemoApplication.class
├── lib
│   ├── aopalliance-1.0.jar
│   ├── spring-beans-4.2.3.RELEASE.jar
│   ├── ...
└── org
    └── springframework
        └── boot
            └── loader
                ├── ExecutableArchiveLauncher.class
                ├── JarLauncher.class
                ├── JavaAgentDetector.class
                ├── LaunchedURLClassLoader.class
                ├── Launcher.class
                ├── MainMethodRunner.class
                ├── ...                

MANIFEST.MF

Manifest-Version: 1.0
Start-Class: com.example.SpringBootDemoApplication
Implementation-Vendor-Id: com.example
Spring-Boot-Version: 1.3.0.RELEASE
Created-By: Apache Maven 3.3.3
Build-Jdk: 1.8.0_60
Implementation-Vendor: Pivotal Software, Inc.
Main-Class: org.springframework.boot.loader.JarLauncher
  1. メインクラスは、これが主な機能の瓶開始され、org.springframework.boot.loader.JarLauncherがあることがわかります。
  2. これは、メイン機能の私たち自身のアプリケーションであり、スタート-Classはcom.example.SpringBootDemoApplicationでもあります。

COM / exampleディレクトリ

これの.classファイルは、アプリケーション内で置かれています。

libディレクトリに

ここでは、Mavenの依存のjarパッケージファイルのアプリケーションに格納されています。このような春豆、ジャーパッケージのような春-MVCなど。

org.springframework.boot.loader

これは、春のブートローダーの.classファイル内に格納されています。

アーカイブコンセプト

  • アーカイブには、この概念は、Linuxにおいてより一般的である、アーカイブです。
  • 通常、圧縮されたtar / zip形式です。
  • jarファイルはzip形式です。

春にアーカイブに加えて、抽象的な概念で起動します。アーカイブは、ファイル・ディレクトリ(ExploadedArchive)することができ、瓶(JarFileArchive)することができます。これは、リソースへの統一されたアクセスのうち抽象化層春ブーツとして理解することができます。

上記デモ-0.0.1-SNAPSHOT.jarには、アーカイブ、jarファイルデモ-0.0.1-SNAPSHOT.jarには内部/ libディレクトリ内の各パケットのアーカイブであるを与えています。

javapublic abstract class Archive { public abstract URL getUrl(); public String getMainClass(); public abstract Collection<Entry> getEntries(); public abstract List<Archive> getNestedArchives(EntryFilter filter);

それぞれが独自のURLを持つアーカイブ、など:

jar:file:/tmp/target/demo-0.0.1-SNAPSHOT.jar!/

別のgetNestedArchives機能、jarファイルのリストは、アーカイブのデモ-0.0.1-SNAPSHOT.jarに/ libの下にある実際のリターン。彼らのURLは次のとおりです。

jar:file:/tmp/target/demo-0.0.1-SNAPSHOT.jar!/lib/aopalliance-1.0.jar
jar:file:/tmp/target/demo-0.0.1-SNAPSHOT.jar!/lib/spring-beans-4.2.3.RELEASE.jar

JarLauncher

MANIFEST.MFジャーメイン機能の起動から見ることができJarLauncherは、以下のワークフローを分析すること、です。

class JarLauncher extends ExecutableArchiveLauncher
class ExecutableArchiveLauncher extends Launcher
  1. デモ-0.01-SNAPSHOT.jarには、アーカイブを作成します。

    JarLauncherは、最初のパスのデモ-0.01-SNAPSHOT.jarにすることを、どこ彼らの瓶見つけ、その後、アーカイブを作成します。

  2. / libにjarファイルの下に取得し、かつLaunchedURLClassLoaderを作成します。

    JarLauncherは、すべてのjarファイルのgetNestedArchives機能下記のデモ-0.0.1-SNAPSHOT.jarに/ libが取得し、リストを作成するには、アーカイブを作成した後。LaunchedURLClassLoader:これらのアーカイブへのURLを取得した後、また、カスタムクラスローダを構築するために使用されるURL []配列を、獲得しました。

    ClassLoaderを作成した後、[スタート] - クラス、すなわちcom.example.SpringBootDemoApplicationに内側からMANIFEST.MFを読み、[主な機能を起動するために、新しいスレッドを作成します。

     /**
      * Launch the application given the archive file and a fully configured classloader.
      */
     protected void launch(String[] args, String mainClass, ClassLoader classLoader)
             throws Exception {
         Runnable runner = createMainMethodRunner(mainClass, args, classLoader);
         Thread runnerThread = new Thread(runner);
         runnerThread.setContextClassLoader(classLoader);
         runnerThread.setName(Thread.currentThread().getName());
         runnerThread.start();
     }
    
     /**
      * Create the {@code MainMethodRunner} used to launch the application.
      */
     protected Runnable createMainMethodRunner(String mainClass, String[] args,
             ClassLoader classLoader) throws Exception {
         Class<?> runnerClass = classLoader.loadClass(RUNNER_CLASS);
         Constructor<?> constructor = runnerClass.getConstructor(String.class,
                 String[].class);
         return (Runnable) constructor.newInstance(mainClass, args);
     }
  3. LaunchedURLClassLoader

    LaunchedURLClassLoaderを除き、通常のURLClassLoaderは、アーカイブの.classからロードする機能を提供することです。

春のブートアプリケーションの起動プロセスの概要

  1. 春のブートアプリケーションをパックした後、それはアプリケーションパケットに依存するJAR、春のブートローダだけでなく、関連するクラスを含むJARパッケージを生成します。
  2. 主な機能のジャーパッケージ開始は、それが瓶下記の負荷/ libのにLaunchedURLClassLoaderを作成するための責任があり、そして新しいスレッド主な機能アプリケーションを起動するために、JarLauncherです。

埋め込みTomcatの起動プロセス

  1. ウェブ環境でのかどうかを判断するには

    春のブートが開始すると、最初に簡単な方法を通じて裁判官にウェブ環境にないサーブレットクラスを見つけるために:

    private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
        "org.springframework.web.context.ConfigurableWebApplicationContext" };
    
    private boolean deduceWebEnvironment() {
        for (String className : WEB_ENVIRONMENT_CLASSES) {
            if (!ClassUtils.isPresent(className, null)) {
                return false;
            }
        }
        return true;
    }
    
  2. ウェブ環境がAnnotationConfigEmbeddedWebApplicationContextを作成している場合は、それ以外の場合は春のコンテキストがAnnotationConfigApplicationContextです。

    //org.springframework.boot.SpringApplication
     protected ConfigurableApplicationContext createApplicationContext() {
         Class<?> contextClass = this.applicationContextClass;
         if (contextClass == null) {
             try {
                 contextClass = Class.forName(this.webEnvironment
                         ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS);
             }
             catch (ClassNotFoundException ex) {
                 throw new IllegalStateException(
                         "Unable create a default ApplicationContext, "
                                 + "please specify an ApplicationContextClass",
                         ex);
             }
         }
         return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
     }
    
  3. EmbeddedServletContainerFactory実装クラスを取得します。

    春ブーツは、対応するWebサーバのEmbeddedServletContainerFactoryを取得することによって開始します。二つのクラスを達成するために使用してTomcatEmbeddedServletContainerFactory JettyEmbeddedServletContainerFactoryされています。

    //TomcatEmbeddedServletContainerFactory
    @Override
    public EmbeddedServletContainer getEmbeddedServletContainer(
            ServletContextInitializer... initializers) {
        Tomcat tomcat = new Tomcat();
        File baseDir = (this.baseDirectory != null ? this.baseDirectory
                : createTempDir("tomcat"));
        tomcat.setBaseDir(baseDir.getAbsolutePath());
        Connector connector = new Connector(this.protocol);
        tomcat.getService().addConnector(connector);
        customizeConnector(connector);
        tomcat.setConnector(connector);
        tomcat.getHost().setAutoDeploy(false);
        tomcat.getEngine().setBackgroundProcessorDelay(-1);
        for (Connector additionalConnector : this.additionalTomcatConnectors) {
            tomcat.getService().addConnector(additionalConnector);
        }
        prepareContext(tomcat.getHost(), initializers);
        return getTomcatEmbeddedServletContainer(tomcat);
    }
    

    TomcatのBASEDIRとして、/tmp/tomcat.2233614112516545210:Tomcatはのような、一時ファイルのディレクトリを作成します。どのような作業ディレクトリとしてTomcatの一時ファイルを格納します。

    それは、このようなデフォルト/ JSP、サーブレットとの比較として、いくつかのサーブレットTomcatを初期化します。

    private void addDefaultServlet(Context context) {
        Wrapper defaultServlet = context.createWrapper();
        defaultServlet.setName("default");
        defaultServlet.setServletClass("org.apache.catalina.servlets.DefaultServlet");
        defaultServlet.addInitParameter("debug", "0");
        defaultServlet.addInitParameter("listings", "false");
        defaultServlet.setLoadOnStartup(1);
        // Otherwise the default location of a Spring DispatcherServlet cannot be set
        defaultServlet.setOverridable(true);
        context.addChild(defaultServlet);
        context.addServletMapping("/", "default");
    }
    
    private void addJspServlet(Context context) {
        Wrapper jspServlet = context.createWrapper();
        jspServlet.setName("jsp");
        jspServlet.setServletClass(getJspServletClassName());
        jspServlet.addInitParameter("fork", "false");
        jspServlet.setLoadOnStartup(3);
        context.addChild(jspServlet);
        context.addServletMapping("*.jsp", "jsp");
        context.addServletMapping("*.jspx", "jsp");
    }
    

アクセスリソースへの春のブートは、Webアプリケーション

春のブートアプリケーションは、JARとしてパッケージ化された場合、どのようにWebリソースにアクセスするには?

アーカイブURLは、実際にはその後、達成クラスローダによって提供されたアクセスクラスパスリソースへの能力によって提供されます。

index.htmlを

たとえば、あなたがindex.htmlをを設定する必要があり、このコードは、SRC /メイン/リソース/静的なディレクトリの下に直接配置することができます。

春ブーツが初期化中に、index.htmlのページへようこそ、それはに対処するためのViewControllerを作成します。

//ResourceProperties
public class ResourceProperties implements ResourceLoaderAware {

    private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" };

    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
            "classpath:/META-INF/resources/", "classpath:/resources/",
            "classpath:/static/", "classpath:/public/" };
            
//WebMvcAutoConfigurationAdapter
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            Resource page = this.resourceProperties.getWelcomePage();
            if (page != null) {
                logger.info("Adding welcome page: " + page);
                registry.addViewController("/").setViewName("forward:index.html");
            }
        }

テンプレート

ページのテンプレートファイルは、SRC /メイン/リソース/テンプレートディレクトリに置くことができるように、これは、このようなThymeleafPropertiesのクラスとして、自分自身のテンプレート実装クラスに対処する必要があることです:

public static final String DEFAULT_PREFIX = "classpath:/templates/";

JSP

JSPページと同様のテンプレート。springmvc JstlViewによって構築された事実で処理されます。

JSPページのディレクトリはspring.view.prefixを設定することによって設定することができます。

spring.view.prefix: /WEB-INF/jsp/

統一されたエラー処理ページ

エラーページでは、春のブーツは、統一のプロセスにBasicErrorControllerを作成することです。

@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController 

対応するページはシンプルなHTMLです。

    @Configuration
    @ConditionalOnProperty(prefix = "server.error.whitelabel", name = "enabled", matchIfMissing = true)
    @Conditional(ErrorTemplateMissingCondition.class)
    protected static class WhitelabelErrorViewConfiguration {

        private final SpelView defaultErrorView = new SpelView(
                "<html><body><h1>Whitelabel Error Page</h1>"
                        + "<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>"
                        + "<div id='created'>${timestamp}</div>"
                        + "<div>There was an unexpected error (type=${error}, status=${status}).</div>"
                        + "<div>${message}</div></body></html>");

        @Bean(name = "error")
        @ConditionalOnMissingBean(name = "error")
        public View defaultErrorView() {
            return this.defaultErrorView;
        }

春のブートMavenのアプリケーションパッケージング工程

依存性のmaven-シェードプラグインを含有する第一ジャーを生成し、クラス関連次いでスプリングブートローダー、およびジャーをバネブートのMaven-プラグインプラグによってMANIFEST.MFに充填しました。

おすすめ

転載: www.cnblogs.com/paulwang92115/p/12216697.html