<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ## Spring啟動器 * SpringBoot工程可以在main方法中執行SpringApplication.run()這種方式來啟動。 ``` @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` * 如果我們需要在SpringBoot啟動過程中添加一些定制代碼(如定制啟動Banner,設置自定義監聽器等,設置啟動拓展,設置啟動環境變量),這種方式就無法滿足我們的要求了。 * 比如我們現在要定制啟動Banner,那么有如下兩種方式。 ``` @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication application = new SpringApplication(Application.class); application.setBannerMode(Banner.Mode.OFF); application.run(args); } } ``` ``` @SpringBootApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder() .sources(Application.class) .bannerMode(Banner.Mode.OFF) .run(args); } } ``` * 只是定制一個banner,代碼就得如此,并不是很優雅,倘若我們有很多個微服務,那每個微服務都這么寫,代碼必定會顯得很冗余。 * 所以我們需要有一個優雅的解決方案,使得每個微服務都調用自定義的啟動器,這樣最終呈現效果就能如原生一樣簡潔優雅。 <br> ## 自定義啟動器 * 核心思路是采用`SpringApplicationBuilder`,將其封裝進一個核心類中進行拓展,以便于微服務啟動之用。 * 啟動器核心代碼如下 ~~~ /** * 項目啟動器,搞定環境變量問題 * * @author Chill */ public class BladeApplication { /** * Create an application context * java -jar app.jar --spring.profiles.active=prod --server.port=2333 * * @param appName application name * @param source The sources * @return an application context created from the current state */ public static ConfigurableApplicationContext run(String appName, Class source, String... args) { SpringApplicationBuilder builder = createSpringApplicationBuilder(appName, source, args); return builder.run(args); } private static SpringApplicationBuilder createSpringApplicationBuilder(String appName, Class source, String... args) { Assert.hasText(appName, "[appName]服務名不能為空"); // 讀取環境變量,使用spring boot的規則 ConfigurableEnvironment environment = new StandardEnvironment(); MutablePropertySources propertySources = environment.getPropertySources(); propertySources.addFirst(new SimpleCommandLinePropertySource(args)); propertySources.addLast(new MapPropertySource(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, environment.getSystemProperties())); propertySources.addLast(new SystemEnvironmentPropertySource(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, environment.getSystemEnvironment())); // 獲取配置的環境變量 String[] activeProfiles = environment.getActiveProfiles(); // 判斷環境:dev、test、prod List<String> profiles = Arrays.asList(activeProfiles); // 預設的環境 List<String> presetProfiles = new ArrayList<>(Arrays.asList(AppConstant.DEV_CDOE, AppConstant.TEST_CODE, AppConstant.PROD_CODE)); // 交集 presetProfiles.retainAll(profiles); // 當前使用 List<String> activeProfileList = new ArrayList<>(profiles); Function<Object[], String> joinFun = StringUtils::arrayToCommaDelimitedString; SpringApplicationBuilder builder = new SpringApplicationBuilder(source); String profile; if (activeProfileList.isEmpty()) { // 默認dev開發 profile = AppConstant.DEV_CDOE; activeProfileList.add(profile); builder.profiles(profile); } else if (activeProfileList.size() == 1) { profile = activeProfileList.get(0); } else { // 同時存在dev、test、prod環境時 throw new RuntimeException("同時存在環境變量:[" + StringUtils.arrayToCommaDelimitedString(activeProfiles) + "]"); } String startJarPath = BladeApplication.class.getResource("/").getPath().split("!")[0]; String activePros = joinFun.apply(activeProfileList.toArray()); System.out.println(String.format("----啟動中,讀取到的環境變量:[%s],jar地址:[%s]----", activePros, startJarPath)); Properties props = System.getProperties(); props.setProperty("spring.application.name", appName); props.setProperty("spring.profiles.active", profile); props.setProperty("info.version", AppConstant.APPLICATION_VERSION); props.setProperty("info.desc", appName); props.setProperty("blade.env", profile); props.setProperty("blade.name", appName); props.setProperty("blade.is-local", String.valueOf(isLocalDev())); props.setProperty("blade.dev-mode", profile.equals(AppConstant.PROD_CODE) ? "false" : "true"); props.setProperty("blade.service.version", AppConstant.APPLICATION_VERSION); props.setProperty("spring.cloud.consul.host", ConsulConstant.CONSUL_HOST); props.setProperty("spring.cloud.consul.port", ConsulConstant.CONSUL_PORT); props.setProperty("spring.cloud.consul.config.format", ConsulConstant.CONSUL_CONFIG_FORMAT); props.setProperty("spring.cloud.consul.watch.delay", ConsulConstant.CONSUL_WATCH_DELAY); props.setProperty("spring.cloud.consul.watch.enabled", ConsulConstant.CONSUL_WATCH_ENABLED); // 加載自定義組件 ServiceLoader<LauncherService> loader = ServiceLoader.load(LauncherService.class); loader.forEach(launcherService -> launcherService.launcher(builder, appName, profile)); return builder; } /** * 判斷是否為本地開發環境 * * @return boolean */ private static boolean isLocalDev() { String osName = System.getProperty("os.name"); return StringUtils.hasText(osName) && !(AppConstant.OS_NAME_LINUX.equals(osName.toUpperCase())); } } ~~~ <br> ## 如何使用 * 以我們之前做的 `blade-demo`模塊啟動為例,看下代碼 ~~~ /** * Demo啟動器 * * @author Chill */ @SpringCloudApplication @EnableFeignClients(AppConstant.BASE_PACKAGES) public class DemoApplication { public static void main(String[] args) { BladeApplication.run(CommonConstant.APPLICATION_DEMO_NAME, DemoApplication.class, args); } } ~~~ * 可以看到非常簡約,與原生并沒有太多變化,只是多了一個appName的參數,此參數正是做為服務名注冊到注冊中心,用于和其他服務分類。 <br> ## 注意點 * 自定義啟動器已經將環境變量也設置好,無需再到`application.yml`中配置`spring.profiles.active`再打包。 * 打包后的app啟動時,若不設置`spring.profiles.active`,則默認為`dev`,如需設置只需在啟動的命令行加上即可。 `java -jar app.jar --spring.profiles.active=prod --server.port=2333` * 無論是打包了fat-jar,還是打包了docker,都只需要打包一次,搭配上注冊中心就可以運行在任何設定好的環境中,這樣一來就實現了`一次打包,處處運行`的理念。 * 開發中,如果要修改為非`DEV`環境,可參考如下配置。 ![](https://box.kancloud.cn/fbf7c8bee685ac446fae5900b7842454_1209x692.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看