最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決SpringBoot使用devtools導(dǎo)致的類型轉(zhuǎn)換異常問題

 更新時(shí)間:2020年08月24日 09:49:55   作者:試水流連  
這篇文章主要介紹了解決SpringBoot使用devtools導(dǎo)致的類型轉(zhuǎn)換異常問題,具有很好的參考價(jià)值,希望對大家有所幫助。 一起跟隨小編過來看看吧

問題:

最近在使用新框架SpringBoot + shiro + spring-data-jpa時(shí),為了體驗(yàn)下spring自帶的熱部署工具的便捷,于是引入了

<dependency> 

   <groupId>org.springframework.boot</groupId> 
   <artifactId>spring-boot-devtools</artifactId> 
   <!-- optional=true,依賴不會(huì)傳遞,該項(xiàng)目依賴devtools;之后依賴myboot項(xiàng)目的項(xiàng)目如果想要使用devtools,需要重新引入 --> 

   <optional>true</optional>
 </dependency>

在起初并沒遇到什么問題,當(dāng)使用shiro的session管理,而且用的sessionDao是redis實(shí)現(xiàn)的,然后再使用Session存取屬性時(shí),發(fā)現(xiàn)存進(jìn)去的屬性,再取出來后,就會(huì)出現(xiàn)類型轉(zhuǎn)換異常ClassCastException

分析:

然后自己寫了一大推單元測試模擬就是沒問題,后來突然意識(shí)到會(huì)不會(huì)是因?yàn)镃lassLoader不同導(dǎo)致的類型轉(zhuǎn)換異常呢,然后注意了下項(xiàng)目啟動(dòng)時(shí)加載項(xiàng)目中的類使用的加載器都是

org.springframework.boot.devtools.restart.classloader.RestartClassLoader

而從shiro session 取出來的對象(從redis中取出經(jīng)過反序列化)的類加載器都是

sun.misc.Launcher.AppClassLoader

很明顯會(huì)導(dǎo)致類型轉(zhuǎn)換異常,原來Spring的dev-tools為了實(shí)現(xiàn)重新裝載class自己實(shí)現(xiàn)了一個(gè)類加載器,來加載項(xiàng)目中會(huì)改變的類,方便重啟時(shí)將新改動(dòng)的內(nèi)容更新進(jìn)來,其實(shí)其中官方文檔中是有做說明的:

By default, any open project in your IDE will be loaded using the “restart” classloader, and any regular .jar file will be loaded using the “base” classloader. If you work on a multi-module project, and not each module is imported into your IDE, you may need to customize things. To do this you can create a META-INF/spring-devtools.properties file. The spring-devtools.properties file can contain restart.exclude. and restart.include. prefixed properties. The include elements are items that should be pulled up into the “restart” classloader, and the exclude elements are items that should be pushed down into the “base” classloader. The value of the property is a regex pattern that will be applied to the classpath.

解決:

方案一、解決方案就是在resources目錄下面創(chuàng)建META-INF文件夾,然后創(chuàng)建spring-devtools.properties文件,文件加上類似下面的配置:

restart.exclude.companycommonlibs=/mycorp-common-[\w-]+.jar restart.include.projectcommon=/mycorp-myproj-[\w-]+.jar

All property keys must be unique. As long as a property starts with restart.include. or restart.exclude. it will be considered. All META-INF/spring-devtools.properties from the classpath will be loaded. You can package files inside your project, or in the libraries that the project consumes.

方案二、不使用spring-boot-devtools

針對方案一作一個(gè)詳細(xì)的案例進(jìn)行分析說明,以及解決問題

首先準(zhǔn)備一個(gè)jar包,里面包含序列化以及反序列化的功能。

并打包,在springboot項(xiàng)目中引入

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- 這個(gè)包是我自己創(chuàng)建的序列化以及反序列化工具包 -->
<dependency>
  <groupId>com.example</groupId>
  <artifactId>devtools-serialization</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

簡單的配置下springboot項(xiàng)目,并模擬使用jar中的序列化工具類進(jìn)行處理對象如下

@SpringBootApplication
public class PortalApplication {
  public static void main(String[] args) throws Exception {
    ConfigurableApplicationContext context = SpringApplication.run(PortalApplication.class, args);
    DemoBean demoBean = new DemoBean();
    SerializationUtils.serialize(demoBean);
    Object deserialize = SerializationUtils.deserialize();
    System.out.println(PortalApplication.class.getClassLoader());
    //這里對象引用是Object類型
    System.out.println(deserialize);
    System.out.println(deserialize.getClass().getClassLoader());
    context.getBeanFactory().destroySingletons();
  }
}

如上,是不會(huì)報(bào)錯(cuò)的,因?yàn)镺bject是bootstrap引導(dǎo)類加載器加載的,因此不會(huì)產(chǎn)生任何問題,

但是如果改成下面這樣

//...
 public static void main(String[] args) throws Exception {
    ConfigurableApplicationContext context = SpringApplication.run(PortalApplication.class, args);
    DemoBean demoBean = new DemoBean();
    SerializationUtils.serialize(demoBean);
    Object deserialize = SerializationUtils.deserialize();
    System.out.println(PortalApplication.class.getClassLoader());
    //注意這里進(jìn)行了一次類型強(qiáng)轉(zhuǎn)
    System.out.println((DemoBean)deserialize);
    System.out.println(deserialize.getClass().getClassLoader());
    context.getBeanFactory().destroySingletons();
  }
  //...

結(jié)果是會(huì)拋出:

Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) Caused by: java.lang.ClassCastException: com.sample.serial.DemoBean cannot be cast to com.sample.serial.DemoBean at com.sample.PortalApplication.main(PortalApplication.java:27) ... 5 more

而觀察上面輸出的ClassLoader信息會(huì)發(fā)現(xiàn)分別為

org.springframework.boot.devtools.restart.classloader.RestartClassLoader@63059d5a sun.misc.Launcher$AppClassLoader@18b4aac2

這就是為什么會(huì)明明沒問題,卻仍然拋了個(gè)ClassCastException的根源所在。

那么如何解決這個(gè)問題呢?

將輸出的ClassLoader信息保持一致即可,要么都是RestartClassLoader要么都是

AppClassLoader

這里參考spring官方文檔給出的配置方法進(jìn)行處理。

在resources下創(chuàng)建META-INF/spring-devtools.properties

如圖:

下一步在spring-devtools.properties添加配置

restart.include.projectcommon=/devtools-serialization-[\\w.-]+.jar

注意這里我需要包含的jar包名稱為devtools-serialization-1.0-SNAPSHOT.jar

配置的key以restart.include.開頭即可

restart.include.*

value 為一個(gè)正則表達(dá)式

下面再次運(yùn)行程序查看效果:

沒有異常產(chǎn)生

控制臺(tái)輸出classLoader信息為

org.springframework.boot.devtools.restart.classloader.RestartClassLoader@1d9fbdd4 DemoBean{age=null, name='null'} org.springframework.boot.devtools.restart.classloader.RestartClassLoader@1d9fbdd4

問題完美解決。

補(bǔ)充知識(shí):Springboot+devtools配置熱部署

Spring Boot提供了spring-boot-devtools這個(gè)模塊來使應(yīng)用支持熱部署,可以提高開發(fā)者的開發(fā)效率,無需手動(dòng)重啟Spring Boot應(yīng)用就能實(shí)現(xiàn)自動(dòng)加載,之前寫了一篇可以自動(dòng)加載springboot靜態(tài)文件的,這次的只需要在原來的基礎(chǔ)上再加一些配置即可實(shí)現(xiàn)springboot工程的熱部署,步驟如下:

1、pom文件增加依賴:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
  </dependency>
</dependencies>
 
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <fork>true</fork> <!--重要-->
      </configuration>
    </plugin>
  </plugins>
</build>

2、yml文件中添加配置使其生效:

# devtools
debug: true
spring:
 devtools:
  restart:
   enabled: true #設(shè)置開啟熱部署
 freemarker:
  cache: false  #頁面不加載緩存,修改即時(shí)生效

3、快捷鍵:Ctrl+Alt+S

4、快捷鍵:Ctrl+Shift+A,輸入Registry,點(diǎn)擊進(jìn)入勾選:

以上這篇解決SpringBoot使用devtools導(dǎo)致的類型轉(zhuǎn)換異常問題就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java實(shí)現(xiàn)對華北、華南、華東和華中四個(gè)區(qū)域的劃分

    Java實(shí)現(xiàn)對華北、華南、華東和華中四個(gè)區(qū)域的劃分

    在Java中,通過定義枚舉類、編寫主程序和進(jìn)行測試,本文詳細(xì)介紹了如何劃分華北、華南、華東和華中四個(gè)區(qū)域,首先定義枚舉類標(biāo)識(shí)區(qū)域,然后通過主程序接收用戶輸入并返回相應(yīng)區(qū)域,最后通過測試用例確保正確性,文章還介紹了甘特圖和餅狀圖的使用
    2024-09-09
  • Java函數(shù)式編程(二):集合的使用

    Java函數(shù)式編程(二):集合的使用

    這篇文章主要介紹了Java函數(shù)式編程(二):集合的使用,本文著重講解了遍歷列表的一些方法,需要的朋友可以參考下
    2014-09-09
  • 關(guān)于synchronized的參數(shù)及其含義

    關(guān)于synchronized的參數(shù)及其含義

    這篇文章主要介紹了synchronized的參數(shù)及其含義詳解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • 淺談SpringBoot實(shí)現(xiàn)異步調(diào)用的幾種方式

    淺談SpringBoot實(shí)現(xiàn)異步調(diào)用的幾種方式

    本文主要介紹了淺談SpringBoot實(shí)現(xiàn)異步調(diào)用的幾種方式,主要包括CompletableFuture異步任務(wù),基于@Async異步任務(wù), TaskExecutor異步任務(wù),感興趣的可以了解一下
    2023-11-11
  • 關(guān)于SpringBoot自定義條件注解與自動(dòng)配置

    關(guān)于SpringBoot自定義條件注解與自動(dòng)配置

    這篇文章主要介紹了關(guān)于SpringBoot自定義條件注解與自動(dòng)配置,Spring Boot的核心功能就是為整合第三方框架提供自動(dòng)配置,而本文則帶著大家實(shí)現(xiàn)了自己的自動(dòng)配置和Starter,需要的朋友可以參考下
    2023-07-07
  • springCloud項(xiàng)目搭建流程步驟分解

    springCloud項(xiàng)目搭建流程步驟分解

    SpringCloud 作為當(dāng)下最為流行的微服務(wù)框架,也越來越多的人去學(xué)習(xí)和使用這個(gè)框架。下面,我將帶大家簡單地認(rèn)識(shí)一下 SpringCloud 框架,以及如何來搭建一個(gè) SpringCloud 項(xiàng)目環(huán)境的教程
    2022-05-05
  • Java zookeeper圖形化工具ZooInspector用法詳解

    Java zookeeper圖形化工具ZooInspector用法詳解

    這篇文章主要介紹了Java zookeeper圖形化工具ZooInspector用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java多線程三種主要實(shí)現(xiàn)方式解析

    Java多線程三種主要實(shí)現(xiàn)方式解析

    這篇文章主要介紹了Java多線程三種主要實(shí)現(xiàn)方式解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 使用Spring Boot的LoggersEndpoint管理日志級別

    使用Spring Boot的LoggersEndpoint管理日志級別

    這篇文章主要為大家介紹了使用Spring Boot的LoggersEndpoint管理日志級別,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • spring的TransactionalEventListener事務(wù)感知源碼解析

    spring的TransactionalEventListener事務(wù)感知源碼解析

    這篇文章主要為大家介紹了spring的TransactionalEventListener事務(wù)感知源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09

最新評論

曲阜市| 托里县| 吐鲁番市| 新疆| 凭祥市| 永和县| 黄浦区| 青龙| 务川| 裕民县| 中超| 石台县| 翁牛特旗| 建瓯市| 通州区| 岳阳县| 平湖市| 郴州市| 永胜县| 临朐县| 南郑县| 襄城县| 西畴县| 泽普县| 平舆县| 泗洪县| 嘉义市| 克山县| 老河口市| 蚌埠市| 名山县| 广南县| 巴南区| 台山市| 郸城县| 斗六市| 揭西县| 东平县| 朝阳市| 马公市| 凌云县|