一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - SpringBoot的reload加載器的方法

SpringBoot的reload加載器的方法

2021-04-14 11:29Mr_Qi Java教程

本篇文章主要介紹了SpringBoot的reload加載器的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

背景

springboot越來越多的被大家所使用SpringBoot DevTool實現熱部署

出現了相同類castException

分析

首先確定出現相同類的castException比如是由于classloader不同造成的。

一個class是否相同取決于兩個因素

  1. classloader相同
  2. class文件相同

即不同classloader解釋出來的class是不同的class

我們在學習jdbc的時候常見的使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
 * Returns the {@code Class} object associated with the class or
 * interface with the given string name. Invoking this method is
 * equivalent to:
 *
 * <blockquote>
 * {@code Class.forName(className, true, currentLoader)}
 * </blockquote>
 *
 * where {@code currentLoader} denotes the defining class loader of
 * the current class.
 *
 * <p> For example, the following code fragment returns the
 * runtime {@code Class} descriptor for the class named
 * {@code java.lang.Thread}:
 *
 * <blockquote>
 *  {@code Class t = Class.forName("java.lang.Thread")}
 * </blockquote>
 * <p>
 * A call to {@code forName("X")} causes the class named
 * {@code X} to be initialized.
 *
 * @param   className  the fully qualified name of the desired class.
 * @return   the {@code Class} object for the class with the
 *       specified name.
 * @exception LinkageError if the linkage fails
 * @exception ExceptionInInitializerError if the initialization provoked
 *      by this method fails
 * @exception ClassNotFoundException if the class cannot be located
 */
public static Class<?> forName(String className)
      throws ClassNotFoundException {
  return forName0(className, true, ClassLoader.getCallerClassLoader());
}

從上面我們可以了解不同的classloader解釋的相同class也無法互相轉換

這樣我們把目標放在devtools上。

我們在springboot中引入了如下依賴

?
1
2
3
4
5
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-devtools</artifactId>
  <optional>true</optional>
</dependency>

那么如何排除devtool的依賴呢?

在application.properties中增加

?
1
spring.devtools.restart.enabled=false

發現啟動時仍然可以看出使用的restartedMain

2018-03-19 22:04:37.641  INFO 53428 --- [restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7443f7a3: startup date [Mon Mar 19 22:03:34 CST 2018]; root of context hierarchy
2018-03-19 22:04:37.654  INFO 53428 --- [restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : Detected ResponseBodyAdvice bean in org.springframework.boot.actuate.autoconfigure.EndpointWebMvcHypermediaManagementContextConfiguration$ActuatorEndpointLinksAdvice
2018-03-19 22:04:37.956  INFO 53428 --- [restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/swagger-ui.html] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-03-19 22:04:37.956  INFO 53428 --- [restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping  

這邊線程名為restartedMain 為啥設置spring.devtools.restart.enabled 無效呢?

代碼

在對應devtools的包中使用了ApplicationListener

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void onApplicationStartingEvent(ApplicationStartingEvent event) {
  // It's too early to use the Spring environment but we should still allow
  // users to disable restart using a System property.
  String enabled = System.getProperty(ENABLED_PROPERTY);
  if (enabled == null || Boolean.parseBoolean(enabled)) {
   String[] args = event.getArgs();
   DefaultRestartInitializer initializer = new DefaultRestartInitializer();
   boolean restartOnInitialize = !AgentReloader.isActive();
   Restarter.initialize(args, false, initializer, restartOnInitialize);
  }
  else {
   Restarter.disable();
  }
}

很明顯其實restarter的開啟是從系統變量中讀取 而并非從spring的環境中讀取 正如注釋所說 其實此刻使用spring的property還太早

因此可以使用系統變量

因此我們可以使用jvm參數

SpringBoot的reload加載器的方法

?
1
-Dspring.devtools.restart.enabled=false

果然此時一切就OK了

2018-03-19 22:18:12.928  INFO 66260 --- [main] com.f6car.base.Application               : The following profiles are active: dev
2018-03-19 22:18:13.131  INFO 66260 --- [main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@2a4354cb: startup date [Mon Mar 19 22:18:13 CST 2018]; root of context hierarchy

那在Spring的配置文件中配置的目的是啥呢?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
 * Restart properties.
 */
public static class Restart {
 
  private static final String DEFAULT_RESTART_EXCLUDES = "META-INF/maven/**,"
     + "META-INF/resources/**,resources/**,static/**,public/**,templates/**,"
     + "**/*Test.class,**/*Tests.class,git.properties,META-INF/build-info.properties";
 
  private static final long DEFAULT_RESTART_POLL_INTERVAL = 1000;
 
  private static final long DEFAULT_RESTART_QUIET_PERIOD = 400;
 
  /**
  * Enable automatic restart.
  */
  private boolean enabled = true;
 
  /**
  * Patterns that should be excluded from triggering a full restart.
  */
  private String exclude = DEFAULT_RESTART_EXCLUDES;
 
  /**
  * Additional patterns that should be excluded from triggering a full restart.
  */
  private String additionalExclude;
 
  /**
  * Amount of time (in milliseconds) to wait between polling for classpath changes.
  */
  private long pollInterval = DEFAULT_RESTART_POLL_INTERVAL;
 
  /**
  * Amount of quiet time (in milliseconds) required without any classpath changes
  * before a restart is triggered.
  */
  private long quietPeriod = DEFAULT_RESTART_QUIET_PERIOD;
 
  /**
  * Name of a specific file that when changed will trigger the restart check. If
  * not specified any classpath file change will trigger the restart.
  */
  private String triggerFile;
 
  /**
  * Additional paths to watch for changes.
  */
  private List<File> additionalPaths = new ArrayList<File>();
 
  public boolean isEnabled() {
   return this.enabled;
  }
 
  public void setEnabled(boolean enabled) {
   this.enabled = enabled;
  }

從代碼中看到似乎是用來配置是否監聽能否自動重啟

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
  * Local Restart Configuration.
  */
  @ConditionalOnProperty(prefix = "spring.devtools.restart", name = "enabled", matchIfMissing = true)
  static class RestartConfiguration {
 
   @Autowired
   private DevToolsProperties properties;
 
   @EventListener
   public void onClassPathChanged(ClassPathChangedEvent event) {
     if (event.isRestartRequired()) {
      Restarter.getInstance().restart(
         new FileWatchingFailureHandler(fileSystemWatcherFactory()));
     }
   }
 
   @Bean
   @ConditionalOnMissingBean
   public ClassPathFileSystemWatcher classPathFileSystemWatcher() {
     URL[] urls = Restarter.getInstance().getInitialUrls();
     ClassPathFileSystemWatcher watcher = new ClassPathFileSystemWatcher(
        fileSystemWatcherFactory(), classPathRestartStrategy(), urls);
     watcher.setStopWatcherOnRestart(true);
     return watcher;
   }
 
   @Bean
   @ConditionalOnMissingBean
   public ClassPathRestartStrategy classPathRestartStrategy() {
     return new PatternClassPathRestartStrategy(
        this.properties.getRestart().getAllExclude());
   }
 
   @Bean
   public HateoasObjenesisCacheDisabler hateoasObjenesisCacheDisabler() {
     return new HateoasObjenesisCacheDisabler();
   }
 
   @Bean
   public FileSystemWatcherFactory fileSystemWatcherFactory() {
     return new FileSystemWatcherFactory() {
 
      @Override
      public FileSystemWatcher getFileSystemWatcher() {
        return newFileSystemWatcher();
      }
 
     };
   }
 
   private FileSystemWatcher newFileSystemWatcher() {
     Restart restartProperties = this.properties.getRestart();
     FileSystemWatcher watcher = new FileSystemWatcher(true,
        restartProperties.getPollInterval(),
        restartProperties.getQuietPeriod());
     String triggerFile = restartProperties.getTriggerFile();
     if (StringUtils.hasLength(triggerFile)) {
      watcher.setTriggerFilter(new TriggerFileFilter(triggerFile));
     }
     List<File> additionalPaths = restartProperties.getAdditionalPaths();
     for (File path : additionalPaths) {
      watcher.addSourceFolder(path.getAbsoluteFile());
     }
     return watcher;
   }
 
  }
 
}

整個根據該配置來返回是否注冊對應的watchService

當然我們也可以移除該jar

需要注意的是 當將這一段代碼注釋時 需要重新

?
1
mvn clean

否則有可能無法自動排除該jar

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://my.oschina.net/qixiaobo025/blog/1648121

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 忘忧草在线社区WWW日本-韩国 | 国产成人手机在线 | 91青青国产在线观看免费 | 国产美女亚洲精品久久久综合 | 男女男精品视频免费观看 | 欧美日韩中文字幕久久伊人 | 爆操萝莉 | 非洲黑人gay巨大 | www国产91| 五月桃花网婷婷亚洲综合 | 好大好深好涨好烫还要 | 欧美撒尿屁股嘘嘘撒尿 | 好大好硬抽搐好爽想要 | 熟睡中的麻麻大白屁股小说 | 国产盗摄wc厕所撒尿视频 | 海角社区在线登录 | yellow视频在线观看免费 | 国产美女亚洲精品久久久综合91 | 成人福利影院 | 亚洲日日操 | 国色天香社区在线视频播放 | 色综合伊人色综合网站中国 | 无码观看AAAAAAAA片 | 吃瓜视频在线观看 | 乌克兰精品摘花处破 | v视界影院成片 | 波多野结衣 在线播放 | 手机国产乱子伦精品视频 | 亚洲国产韩国欧美在线不卡 | 国产一区在线播放 | 四虎影视免费观看免费观看 | 青草青青在线视频 | 国产一级精品高清一级毛片 | 波多野结衣中文字幕 | 青青青国产精品国产精品美女 | wc凹凸撒尿间谍女厕hd | 亚洲精品午夜级久久久久 | 精品福利一区二区免费视频 | 99久久精品国产片久人 | 236z最新伦理 | eee在线播放成人免费 |