电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

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

瀏覽:44日期:2023-05-01 08:37:05

問題:

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

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

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

分析:

然后自己寫了一大推單元測試模擬就是沒問題,后來突然意識到會不會是因為ClassLoader不同導致的類型轉(zhuǎn)換異常呢,然后注意了下項目啟動時加載項目中的類使用的加載器都是

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

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

sun.misc.Launcher.AppClassLoader

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

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

針對方案一作一個詳細的案例進行分析說明,以及解決問題

首先準備一個jar包,里面包含序列化以及反序列化的功能。

并打包,在springboot項目中引入

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

簡單的配置下springboot項目,并模擬使用jar中的序列化工具類進行處理對象如下

@SpringBootApplicationpublic 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(); }}

如上,是不會報錯的,因為Object是bootstrap引導類加載器加載的,因此不會產(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()); //注意這里進行了一次類型強轉(zhuǎn) System.out.println((DemoBean)deserialize); System.out.println(deserialize.getClass().getClassLoader()); context.getBeanFactory().destroySingletons(); } //...

結(jié)果是會拋出:

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信息會發(fā)現(xiàn)分別為

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

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

那么如何解決這個問題呢?

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

AppClassLoader

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

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

如圖:

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

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

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

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

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

restart.include.*

value 為一個正則表達式

下面再次運行程序查看效果:

沒有異常產(chǎn)生

控制臺輸出classLoader信息為

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

問題完美解決。

補充知識:Springboot+devtools配置熱部署

Spring Boot提供了spring-boot-devtools這個模塊來使應用支持熱部署,可以提高開發(fā)者的開發(fā)效率,無需手動重啟Spring Boot應用就能實現(xiàn)自動加載,之前寫了一篇可以自動加載springboot靜態(tài)文件的,這次的只需要在原來的基礎(chǔ)上再加一些配置即可實現(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文件中添加配置使其生效:

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

3、快捷鍵:Ctrl+Alt+S

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

4、快捷鍵:Ctrl+Shift+A,輸入Registry,點擊進入勾選:

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

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

標簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 数显恒温油浴-电砂浴-高温油浴振荡器-常州迈科诺仪器有限公司 | 卷筒电缆-拖链电缆-特种柔性扁平电缆定制厂家「上海缆胜」 | 雷蒙磨,雷蒙磨粉机,雷蒙磨机 - 巩义市大峪沟高峰机械厂 | 欧景装饰设计工程有限公司-无锡欧景装饰官网 | 粉末包装机,拆包机厂家,价格-上海强牛包装机械设备有限公司 | 新型游乐设备,360大摆锤游乐设备「诚信厂家」-山东方鑫游乐设备 新能源汽车电池软连接,铜铝复合膜柔性连接,电力母排-容发智能科技(无锡)有限公司 | 蜘蛛车-登高车-高空作业平台-高空作业车-曲臂剪叉式升降机租赁-重庆海克斯公司 | 厦门ISO认证|厦门ISO9001认证|厦门ISO14001认证|厦门ISO45001认证-艾索咨询专注ISO认证行业 | 锂电混合机-新能源混合机-正极材料混料机-高镍,三元材料混料机-负极,包覆混合机-贝尔专业混合混料搅拌机械系统设备厂家 | 焊接减速机箱体,减速机箱体加工-淄博博山泽坤机械厂 | 心得体会网_心得体会格式范文模板 | 禹城彩钢厂_钢结构板房_彩钢复合板-禹城泰瑞彩钢复合板加工厂 | 玻璃钢罐_玻璃钢储罐_盐酸罐厂家-河北华盛节能设备有限公司 | 电抗器-能曼电气-电抗器专业制造商| 迪威娱乐|迪威娱乐客服|18183620002 | 冷油器-冷油器换管改造-连云港灵动列管式冷油器生产厂家 | 选矿设备,选矿生产线,选矿工艺,选矿技术-昆明昆重矿山机械 | 悬浮拼装地板_篮球场木地板翻新_运动木地板价格-上海越禾运动地板厂家 | 2025福建平潭岛旅游攻略|蓝眼泪,景点,住宿攻略-趣平潭网 | 浙江栓钉_焊钉_剪力钉厂家批发_杭州八建五金制造有限公司 | 福州仿石漆加盟_福建仿石漆厂家-外墙仿石漆加盟推荐铁壁金钢(福建)新材料科技有限公司有保障 | 超声波分散机-均质机-萃取仪-超声波涂料分散设备-杭州精浩 | 石油/泥浆/不锈钢防腐/砂泵/抽砂泵/砂砾泵/吸砂泵/压滤机泵 - 专业石油环保专用泵厂家 | 雷冲击高压发生器-水内冷直流高压发生器-串联谐振分压器-武汉特高压电力科技有限公司 | uv机-uv灯-uvled光固化机-生产厂家-蓝盾机电 | 磨煤机配件-高铬辊套-高铬衬板-立磨辊套-盐山县宏润电力设备有限公司 | 潜水搅拌机-双曲面搅拌机-潜水推进器|奥伯尔环保 | 泵阀展|阀门展|水泵展|流体机械展 -2025上海国际泵管阀展览会flowtech china | 粤丰硕水性环氧地坪漆-防静电自流平厂家-环保地坪涂料代理 | 合肥卓创建筑装饰,专业办公室装饰、商业空间装修与设计。 | 噪声治理公司-噪音治理专业隔音降噪公司| 选矿设备-新型重选设备-金属矿尾矿重选-青州冠诚重工机械有限公司 | 湖南教师资格网-湖南教师资格证考试网| 工业PH计|工业ph酸度计|在线PH计价格-合肥卓尔仪器仪表有限公司 济南画室培训-美术高考培训-山东艺霖艺术培训画室 | 机构创新组合设计实验台_液压实验台_气动实训台-戴育教仪厂 | 广州二手电缆线回收,旧电缆回收,广州铜线回收-广东益福电缆线回收公司 | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | 长沙中央空调维修,中央空调清洗维保,空气能热水工程,价格,公司就找维小保-湖南维小保环保科技有限公司 | 中红外QCL激光器-其他连续-半导体连续激光器-筱晓光子 | 猎头招聘_深圳猎头公司_知名猎头公司 | 寮步纸箱厂_东莞纸箱厂 _东莞纸箱加工厂-东莞市寮步恒辉纸制品厂 |