{"id":226,"date":"2024-12-22T19:58:37","date_gmt":"2024-12-22T19:58:37","guid":{"rendered":"https:\/\/www.isvmspace.com\/?p=226"},"modified":"2024-12-22T19:58:37","modified_gmt":"2024-12-22T19:58:37","slug":"springboot%e5%90%af%e5%8a%a8%e5%8e%9f%e7%90%86%e5%88%86%e6%9e%90","status":"publish","type":"post","link":"https:\/\/www.isvmspace.com\/?p=226","title":{"rendered":"SpringBoot\u542f\u52a8\u539f\u7406\u5206\u6790"},"content":{"rendered":"<h2>1. SpringBoot\u5982\u4f55\u901a\u8fc7jar\u5305\u542f\u52a8<\/h2>\n<h3>1.1. java -jar\u505a\u4e86\u4ec0\u4e48\uff1f<\/h3>\n<p>https:\/\/docs.oracle.com\/javase\/tutorial\/deployment\/jar\/run.html<\/p>\n<pre><code class=\"language-text line-numbers\">To indicate which class is the application's entry point, you must add a Main-Class header to the JAR file's manifest. The header takes the form:\nMain-Class: classname\n<\/code><\/pre>\n<p>Java\u6ca1\u6709\u63d0\u4f9b\u4efb\u4f55\u6807\u51c6\u7684\u65b9\u5f0f\u6765\u52a0\u8f7d\u5d4c\u5957\u7684jar\u6587\u4ef6\uff08\u5373\uff0c\u5b83\u4eec\u672c\u8eab\u5305\u542b\u5728jar\u4e2d\u7684jar\u6587\u4ef6\uff09\u3002<\/p>\n<p>Jar\u5305\u7684\u6253\u5305\u63d2\u4ef6\u53ca\u6838\u5fc3\u65b9\u6cd5<br \/>\nSpring Boot\u9879\u76ee\u7684pom.xml\u6587\u4ef6\u4e2d\u4f7f\u7528\u5982\u4e0b\u63d2\u4ef6\u8fdb\u884c\u6253\u5305\uff1a<\/p>\n<pre><code class=\"language-maven line-numbers\">&lt;build&gt;\n    &lt;plugins&gt;\n        &lt;plugin&gt;\n            &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n            &lt;artifactId&gt;spring-boot-maven-plugin&lt;\/artifactId&gt;\n        &lt;\/plugin&gt;\n    &lt;\/plugins&gt;\n&lt;\/build&gt;\n<\/code><\/pre>\n<p>\u6267\u884cmaven clean package\u4e4b\u540e\uff0c\u4f1a\u751f\u6210\u4e24\u4e2a\u6587\u4ef6\uff1a<\/p>\n<pre><code class=\"language-text line-numbers\">spring-boot-start-demo-1.0-SNAPSHOT.jar\nspring-boot-start-demo-1.0-SNAPSHOT.jar.original\n<\/code><\/pre>\n<p>spring-boot-maven-plugin\u9ed8\u8ba4\u67095\u4e2agoals\uff1a<\/p>\n<pre><code class=\"language-text line-numbers\">repackage\u3001run\u3001start\u3001stop\u3001build-info\n<\/code><\/pre>\n<p>\u5728\u6253\u5305\u7684\u65f6\u5019\u9ed8\u8ba4\u4f7f\u7528\u7684\u662frepackage\u3002<\/p>\n<h3>1.2. jar\u5305\u76ee\u5f55\u7ed3\u6784<\/h3>\n<pre><code class=\"language-text line-numbers\">spring-boot-start-demo-1.0-SNAPSHOT\n\n\u251c\u2500\u2500 META-INF\n\u2502   \u2514\u2500\u2500 MANIFEST.MF\n\u251c\u2500\u2500 BOOT-INF\n\u2502   \u251c\u2500\u2500 classes\n\u2502   \u2502   \u2514\u2500\u2500 \u5e94\u7528\u7a0b\u5e8f\u7c7b\n\u2502   \u2514\u2500\u2500 lib\n\u2502       \u2514\u2500\u2500 \u7b2c\u4e09\u65b9\u4f9d\u8d56jar\n\u2514\u2500\u2500 org\n    \u2514\u2500\u2500 springframework\n        \u2514\u2500\u2500 boot\n            \u2514\u2500\u2500 loader\n                \u2514\u2500\u2500 springboot\u542f\u52a8\u7a0b\u5e8f\n<\/code><\/pre>\n<p>META-INF\u5185\u5bb9\uff1a<br \/>\n\u5728\u4e0a\u8ff0\u76ee\u5f55\u7ed3\u6784\u4e2d\uff0cMANIFEST.MF\u8bb0\u5f55\u4e86\u76f8\u5173jar\u5305\u7684\u57fa\u7840\u4fe1\u606f\uff0c\u5305\u62ec\u5165\u53e3\u7a0b\u5e8f\u7b49\uff1a<\/p>\n<pre><code class=\"language-text line-numbers\">Manifest-Version: 1.0\nImplementation-Title: spring-boot-start-demo\nImplementation-Version: 1.0-SNAPSHOT\nStart-Class: com.isvmspace.demo.SpringBootDemoApplication\nSpring-Boot-Classes: BOOT-INF\/classes\/\nSpring-Boot-Lib: BOOT-INF\/lib\/\nBuild-Jdk-Spec: 1.8\nSpring-Boot-Version: 2.1.17.RELEASE\nCreated-By: Maven Archiver 3.4.0\nMain-Class: org.springframework.boot.loader.JarLauncher\n<\/code><\/pre>\n<p><strong>Main-Class<\/strong>\u662forg.springframework.boot.loader.JarLauncher \uff0c\u8fd9\u4e2a\u662fjar\u542f\u52a8\u7684Main\u51fd\u6570\u3002<br \/>\n<strong>Start-Class<\/strong>\u662fcom.isvmspace.demo.SpringBootDemoApplication\uff0c\u8fd9\u4e2a\u662f\u6211\u4eec\u5e94\u7528\u81ea\u5df1\u7684Main\u51fd\u6570\u3002<\/p>\n<h3>1.3. JarLauncher\u6e90\u7801\u89e3\u6790<\/h3>\n<p>\u5f15\u5165JarLauncher\u7684\u4f9d\u8d56\uff0c\u67e5\u770b\u6e90\u7801<\/p>\n<pre><code class=\"language-maven line-numbers\">&lt;dependency&gt;\n  &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n  &lt;artifactId&gt;spring-boot-loader&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n<\/code><\/pre>\n<p>JarLauncher\u7684\u4f9d\u8d56\u5173\u7cfb\uff1a<\/p>\n<pre><code class=\"language-text line-numbers\">class JarLauncher extends ExecutableArchiveLauncher\nclass ExecutableArchiveLauncher extends Launcher\n<\/code><\/pre>\n<p>JarLauncher\u7684\u6e90\u7801\u5206\u6790<\/p>\n<pre><code class=\"language-java line-numbers\">public class JarLauncher extends ExecutableArchiveLauncher {\n    public JarLauncher() {}\n    public static void main(String[] args) throws Exception {\n        \/\/ \u65b0\u5efa\u4e86JarLauncher\u5e76\u8c03\u7528\u7236\u7c7bLauncher\u4e2d\u7684launch\u65b9\u6cd5\u542f\u52a8\u7a0b\u5e8f\n        new JarLauncher().launch(args);\n    }\n}\n<\/code><\/pre>\n<p>\u5728\u521b\u5efaJarLauncher\u65f6\uff0c\u7236\u7c7bExecutableArchiveLauncher\u627e\u5230\u81ea\u5df1\u6240\u5728\u7684jar\uff0c\u5e76\u521b\u5efaarchive\u3002<\/p>\n<pre><code class=\"language-java line-numbers\">public abstract class ExecutableArchiveLauncher extends Launcher {\n    private final Archive archive;\n    public ExecutableArchiveLauncher() {\n        try {\n            \/\/ \u627e\u5230\u81ea\u5df1\u6240\u5728\u7684jar\uff0c\u5e76\u8c03\u7528\u7236\u7c7bLauncher\u65b9\u6cd5\u521b\u5efaArchive\n            this.archive = createArchive();\n        }\n        catch (Exception ex) {\n            throw new IllegalStateException(ex);\n        }\n    }\n}\n<\/code><\/pre>\n<p>Launcher\u7684\u6838\u5fc3\u6267\u884c\u65b9\u6cd5launch<\/p>\n<pre><code class=\"language-java line-numbers\">public abstract class Launcher {\n    \/**\n     * Launch the application. This method is the initial entry point that should be\n     * called by a subclass {@code public static void main(String[] args)} method.\n     *\/\n    protected void launch(String[] args) throws Exception {\n        JarFile.registerUrlProtocolHandler();\n        \/\/ \u83b7\u53d6archives,\u5e76\u4e14\u5f97ClassLoader\n        ClassLoader classLoader = createClassLoader(getClassPathArchives());\n        \/\/ \u83b7\u53d6\u542f\u52a8\u7c7b\uff0c\u5e76\u4e14\u901a\u8fc7\u53cd\u5c04\u8fd0\u884c\u4e3b\u7c7b\u7684main()\n        launch(args, getMainClass(), classLoader);\n    }\n}\n<\/code><\/pre>\n<h2>2. SpringBoot\u5982\u4f55\u542f\u52a8Spring\u5bb9\u5668<\/h2>\n<h3>2.1. \u81ea\u5b9a\u4e49springboot\u5e94\u7528\u542f\u52a8\u7c7b<\/h3>\n<pre><code class=\"language-java line-numbers\">public class SpringBootDemoApplication {\n    public static void main(String[] args) {\n        SpringApplication.run(SpringBootDemoApplication.class, args);\n    }\n}\n<\/code><\/pre>\n<h3>2.2. \u521b\u5efaSpringApplication\u5e76\u542f\u52a8<\/h3>\n<p>org.springframework.boot.SpringApplication#run<\/p>\n<pre><code class=\"language-java line-numbers\">public static ConfigurableApplicationContext run(Class&lt;?&gt;[] primarySources, String[] args) {\n   return new SpringApplication(primarySources).run(args);\n}\n<\/code><\/pre>\n<h5>2.2.1. SpringApplication\u6784\u9020\u51fd\u6570\u5206\u6790<\/h5>\n<pre><code class=\"language-java line-numbers\">public SpringApplication(ResourceLoader resourceLoader, Class&lt;?&gt;... primarySources) {\n   this.resourceLoader = resourceLoader;\n   Assert.notNull(primarySources, \"PrimarySources must not be null\");\n   \/\/ \u5c06\u542f\u52a8\u7c7b\u653e\u5165primarySources \n   this.primarySources = new LinkedHashSet&lt;&gt;(Arrays.asList(primarySources));\n   \/\/ \u6839\u636eclasspath \u4e0b\u7684\u7c7b\uff0c\u63a8\u7b97\u5f53\u524dweb\u5e94\u7528\u7c7b\u578b(webFlux, servlet)\n   this.webApplicationType = WebApplicationType.deduceFromClasspath();\n   \/\/ \u53bbspring.factories \u4e2d\u53bb\u83b7\u53d6\u6240\u6709key:org.springframework.context.ApplicationContextInitializer\n   setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));\n   \/\/\u53bbspring.factories \u4e2d\u53bb\u83b7\u53d6\u6240\u6709key: org.springframework.context.ApplicationListener\n   setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));\n   \/\/ \u6839\u636emain\u65b9\u6cd5\u63a8\u7b97\u51famainApplicationClass \n   this.mainApplicationClass = deduceMainApplicationClass();\n}\n<\/code><\/pre>\n<h5>2.2.2. SpringApplication#run\u6838\u5fc3\u6e90\u7801\u89e3\u6790<\/h5>\n<p>org.springframework.boot.SpringApplication#run(java.lang.String...)<\/p>\n<pre><code class=\"language-java line-numbers\">    \/**\n     * \u8fd0\u884cSpring application, \u521b\u5efa\u5e76\u4e14\u66f4\u65b0ApplicationContext.\n     * @param args \u547d\u4ee4\u884c\u53c2\u6570\n     * @return ApplicationContext\n     *\/\npublic ConfigurableApplicationContext run(String... args) {\n    \/\/ \u7528\u6765\u8bb0\u5f55\u5f53\u524dspringboot\u542f\u52a8\u8017\u65f6\n   StopWatch stopWatch = new StopWatch();\n   \/\/ \u8bb0\u5f55\u542f\u52a8\u5f00\u59cb\u65f6\u95f4\n   stopWatch.start();\n   \/\/ spring\u4e0a\u4e0b\u6587\u7684\u63a5\u53e3\uff0c \u63a5\u6536ApplicationContext\u5b9e\u73b0\n   ConfigurableApplicationContext context = null;\n   Collection&lt;SpringBootExceptionReporter&gt; exceptionReporters = new ArrayList&lt;&gt;();\n   configureHeadlessProperty();\n   \/\/ \u901a\u8fc7spring.factroies\u4e2d\u8bfb\u53d6\u4e86SpringApplicationRunListener \u7684\u7ec4\u4ef6\uff0c\u7528\u6765\u53d1\u5e03\u4e8b\u4ef6\u6216\u8005\u8fd0\u884c\u76d1\u542c\u5668\n   SpringApplicationRunListeners listeners = getRunListeners(args);\n   \/\/ \u89e6\u53d1ApplicationStartingEvent\u7684\u76d1\u542c\u8005\u6267\u884conApplicationEvent\n   listeners.starting();\n   try {\n       \/\/ \u6839\u636e\u547d\u4ee4\u884c\u53c2\u6570 \u5b9e\u4f8b\u5316\u4e00\u4e2aApplicationArguments \n      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);\n      \/\/ \u9884\u521d\u59cb\u5316\u73af\u5883\uff1a \u8bfb\u53d6\u73af\u5883\u53d8\u91cf\uff0c\u8bfb\u53d6\u914d\u7f6e\u6587\u4ef6\u4fe1\u606f\uff08\u57fa\u4e8e\u76d1\u542c\u5668\uff09\n      ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);\n      \/\/ \u5ffd\u7565beaninfo\u7684bean\n      configureIgnoreBeanInfo(environment);\n      \/\/ \u6253\u5370Banner\n      Banner printedBanner = printBanner(environment);\n      \/\/ \u6839\u636ewebApplicationType\u521b\u5efaSpring\u4e0a\u4e0b\u6587  \n      context = createApplicationContext();\n      exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,\n            new Class[] { ConfigurableApplicationContext.class }, context);\n      \/\/ \u9884\u521d\u59cb\u5316spring\u4e0a\u4e0b\u6587\n      prepareContext(context, environment, listeners, applicationArguments, printedBanner);\n      \/\/ \u52a0\u8f7dspring ioc \u5bb9\u5668   **\u76f8\u5f53\u91cd\u8981   \u7531\u4e8e\u662f\u4f7f\u7528AnnotationConfigServletWebServerApplicationContext \u542f\u52a8\u7684spring\u5bb9\u5668\u6240\u4ee5springboot\u5bf9\u5b83\u505a\u4e86\u6269\u5c55\uff1a\n      \/\/  \u52a0\u8f7d\u81ea\u52a8\u914d\u7f6e\u7c7b\uff1ainvokeBeanFactoryPostProcessors \uff0c  \u521b\u5efaservlet\u5bb9\u5668onRefresh\n      refreshContext(context);\n      afterRefresh(context, applicationArguments);\n      stopWatch.stop();\n      if (this.logStartupInfo) {\n         new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);\n      }\n      \/\/ \u53d1\u5e03ApplicationStartedEvent\u4e8b\u4ef6\n      listeners.started(context);\n      callRunners(context, applicationArguments);\n   }\n   catch (Throwable ex) {\n      handleRunFailure(context, ex, exceptionReporters, listeners);\n      throw new IllegalStateException(ex);\n   }\n\n   try {\n      \/\/ \u53d1\u5e03ApplicationReadyEvent\u4e8b\u4ef6\n      listeners.running(context);\n   }\n   catch (Throwable ex) {\n      handleRunFailure(context, ex, exceptionReporters, null);\n      throw new IllegalStateException(ex);\n   }\n   return context;\n}\n<\/code><\/pre>\n<div STYLE=\"page-break-after: always;\"><\/div>\n<p>org.springframework.boot.SpringApplication#prepareEnvironment<\/p>\n<pre><code class=\"language-java line-numbers\">    \/**\n     * \u9884\u521d\u59cb\u5316\u73af\u5883\n     *\n     * @param listeners            \u76d1\u542c\u5668\n     * @param applicationArguments \u547d\u4ee4\u884c\u53c2\u6570\n     * @return \u73af\u5883\u4fe1\u606f\n     *\/\nprivate ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,\n      ApplicationArguments applicationArguments) {\n   \/\/ \u6839\u636ewebApplicationType \u521b\u5efaEnvironment  \u521b\u5efa\u5c31\u4f1a\u8bfb\u53d6\uff1a java\u73af\u5883\u53d8\u91cf\u548c\u7cfb\u7edf\u73af\u5883\u53d8\u91cf\n   ConfigurableEnvironment environment = getOrCreateEnvironment();\n   \/\/ \u5c06\u547d\u4ee4\u884c\u53c2\u6570\u8bfb\u53d6\u73af\u5883\u53d8\u91cf\u4e2d\n   configureEnvironment(environment, applicationArguments.getSourceArgs());\n   \/\/ \u5c06configurationProperties\u7684\u914d\u7f6e\u4fe1\u606f \u653e\u5728\u7b2c\u4e00\u4f4d\n   ConfigurationPropertySources.attach(environment);\n   \/\/ \u53d1\u5e03ApplicationEnvironmentPreparedEvent\u7684\u76d1\u542c\u5668\n   \/\/ ConfigFileApplicationListener\u8bfb\u53d6\u4e86\u5168\u5c40\u914d\u7f6e\u6587\u4ef6\n   listeners.environmentPrepared(environment);\n   \/\/ \u5c06\u6240\u6709spring.main \u5f00\u5934\u7684\u914d\u7f6e\u4fe1\u606f\u7ed1\u5b9aSpringApplication\n   bindToSpringApplication(environment);\n   if (!this.isCustomEnvironment) {\n      environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,\n            deduceEnvironmentClass());\n   }\n   \/\/\u66f4\u65b0PropertySources\n   ConfigurationPropertySources.attach(environment);\n   return environment;\n}\n<\/code><\/pre>\n<p>org.springframework.boot.SpringApplication#prepareContext<\/p>\n<pre><code class=\"language-java line-numbers\">    \/**\n     * \u9884\u521d\u59cb\u5316spring\u4e0a\u4e0b\u6587\n     *\n     * @param context              \u4e0a\u4e0b\u6587\n     * @param environment          \u73af\u5883\n     * @param listeners            \u76d1\u542c\u5668\n     * @param applicationArguments \u547d\u4ee4\u884c\u53c2\u6570\n     * @param printedBanner        banner\n     *\/\nprivate void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,\n      SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {\n   context.setEnvironment(environment);\n   postProcessApplicationContext(context);\n   \/\/ \u62ff\u5230\u4e4b\u524d\u8bfb\u53d6\u5230\u6240\u6709ApplicationContextInitializer\u7684\u7ec4\u4ef6\uff0c \u5faa\u73af\u8c03\u7528initialize\u65b9\u6cd5\n   applyInitializers(context);\n   \/\/ \u53d1\u5e03\u4e86ApplicationContextInitializedEvent\n   listeners.contextPrepared(context);\n   if (this.logStartupInfo) {\n      logStartupInfo(context.getParent() == null);\n      logStartupProfileInfo(context);\n   }\n   \/\/ \u83b7\u53d6\u5f53\u524dspring\u4e0a\u4e0b\u6587beanFactory (\u8d1f\u8d23\u521b\u5efabean)\n   ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();\n   \/\/ \u5728SpringBoot \u5728\u8fd9\u91cc\u8bbe\u7f6e\u4e86\u4e0d\u5141\u8bb8\u8986\u76d6\uff0c \u5f53\u51fa\u73b02\u4e2a\u91cd\u540d\u7684bean \u4f1a\u629b\u51fa\u5f02\u5e38\n   beanFactory.registerSingleton(\"springApplicationArguments\", applicationArguments);\n   if (printedBanner != null) {\n      beanFactory.registerSingleton(\"springBootBanner\", printedBanner);\n   }\n   \/\/ \u5728Spring\u4e0b \u5982\u679c\u51fa\u73b02\u4e2a\u91cd\u540d\u7684bean, \u5219\u540e\u8bfb\u53d6\u5230\u7684\u4f1a\u8986\u76d6\u524d\u9762\n   if (beanFactory instanceof DefaultListableBeanFactory) {\n      ((DefaultListableBeanFactory) beanFactory)\n            .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);\n   }\n   \/\/ Load the sources\n   Set&lt;Object&gt; sources = getAllSources();\n   Assert.notEmpty(sources, \"Sources must not be empty\");\n   \/\/ \u8bfb\u53d6\u4e3b\u542f\u52a8\u7c7b\n   load(context, sources.toArray(new Object[0]));\n   \/\/ \u8bfb\u53d6\u5b8c\u914d\u7f6e\u7c7b\u540e\u53d1\u9001ApplicationPreparedEvent\n   listeners.contextLoaded(context);\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>1. SpringBoot\u5982\u4f55\u901a\u8fc7jar\u5305\u542f\u52a8 1.1. java -jar\u505a\u4e86\u4ec0\u4e48\uff1f https:\/\/doc [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"_links":{"self":[{"href":"https:\/\/www.isvmspace.com\/index.php?rest_route=\/wp\/v2\/posts\/226"}],"collection":[{"href":"https:\/\/www.isvmspace.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.isvmspace.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.isvmspace.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.isvmspace.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=226"}],"version-history":[{"count":4,"href":"https:\/\/www.isvmspace.com\/index.php?rest_route=\/wp\/v2\/posts\/226\/revisions"}],"predecessor-version":[{"id":230,"href":"https:\/\/www.isvmspace.com\/index.php?rest_route=\/wp\/v2\/posts\/226\/revisions\/230"}],"wp:attachment":[{"href":"https:\/\/www.isvmspace.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=226"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.isvmspace.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=226"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.isvmspace.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=226"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}