時間:2017年12月01日星期五
說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com
教學源碼:無
學習源碼:https://github.com/zccodere/s...
熱部署的使用場景
本地調式 線上發布
熱部署的使用優點
無論本地還是線上,都適用 無需重啟服務器:提高開發、調式效率、提升發布、運維效率、降低運維成本
前置知識
掌握Java語言 有一定的Spring開發經驗 掌握構建Spring Boot項目的方法
課程提綱
原理解析 案例分析 項目演示 測試驗證 發布程序 課程總結第二章:原理解析 2-1 部署加載
Java熱部署與熱加載聯系
不重啟服務器編譯或部署項目 基于Java的類加載器實現
Java熱部署與熱加載的區別
部署方式 --熱部署在服務器運行時重新部署項目 --熱加載在運行時重新加載class 實現原理 --熱部署直接重新加載整個應用 --熱加載在運行時重新加載class 使用場景 --熱部署更多的是在生產環境使用 --熱加載則更多的是在開發環境使用2-2 原理解析
Java類的加載過程
類加載的五個階段
Java類加載器特點
1.由AppClassLoader(系統類加載器)開始加載指定的類 2.類加載器將加載任務交給其父類,如果其父類找不到,再由自己去加載 3.BootstrapLoader(啟動類加載器)是最頂級的類加載器
Java類的熱部署
類的熱加載 配置Tomcat
通過類的熱加載實現熱部署
通過配置Tomcat實現熱部署
1.直接把項目web文件夾放在webapps里 2.在tomcat/conf/server.xml中的第三章:案例分析 3-1 案例介紹內部添加 標簽 3.在%tomcat_home%/conf/Catalina/localhost中添加一個XML
寫一個Java類熱加載的實際案例,要求如下
1.類層次結構清晰,修改某一個Java類文件不需要重啟服務或者重新編譯運行程序 2.可適當的運用一些設計模式使代碼結構更加清晰明了,比如工廠模式等3-2 案例實現
創建名為classloader的gradle工程build.gradle腳本如下
apply plugin: "java" apply plugin: "eclipse" group = "com.myimooc" version = "0.0.1-SNAPSHOT" sourceCompatibility = 1.8 repositories { maven{ url "http://maven.aliyun.com/nexus/content/groups/public/"} mavenCentral() } dependencies { }
代碼編寫
1.編寫MyClassLoader類
package com.myimooc.classloader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; /** * @title 自定義Java類加載器 * @describe 來實現Java類的熱加載 * @author zc * @version 1.0 2017-12-01 */ public class MyClassLoader extends ClassLoader{ /** 要加載的Java類的classpath路徑 */ private String classpath; public MyClassLoader(String classpath) { super(ClassLoader.getSystemClassLoader()); this.classpath = classpath; } @Override protected Class> findClass(String name) throws ClassNotFoundException { byte[] data = this.loadClassData(name); return this.defineClass(name, data, 0, data.length); } /** * @title 加載class文件中的內容 * @describe 加載class文件中的內容 * @author zc * @version 1.0 2017-12-01 */ private byte[] loadClassData(String name) { try{ name = name.replace(".", "http://"); FileInputStream is = new FileInputStream(new File(this.classpath + name +".class")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int b = 0; while((b = is.read()) != -1){ baos.write(b); } is.close(); return baos.toByteArray(); }catch (Exception e) { e.printStackTrace(); } return null; } }
2.編寫BaseManager類
package com.myimooc.classloader; /** * @title 標識接口 * @describe 實現這個接口的子類需要動態更新 * @author zc * @version 1.0 2017-12-01 */ public interface BaseManager { public void logic(); }
3.編寫MyManager類
package com.myimooc.classloader; /** * @title 接口實現類 * @describe BaseManager的子類,此類需要實現Java類的熱加載功能 * @author zc * @version 1.0 2017-12-01 */ public class MyManager implements BaseManager { @Override public void logic() { System.out.println("學習如何實現Java類的熱加載案例"); } }
4.編寫LoadInfo類
package com.myimooc.classloader; /** * @title 類加載信息 * @describe 封裝加載類的信息 * @author zc * @version 1.0 2017-12-01 */ public class LoadInfo { /** 自定義的類加載器 */ private MyClassLoader myLoader; /** 記錄要加載類的時間戳,加載的時間 */ private long loadTime; private BaseManager manager; public LoadInfo(MyClassLoader myLoader, long loadTime) { super(); this.myLoader = myLoader; this.loadTime = loadTime; } public MyClassLoader getMyLoader() { return myLoader; } public void setMyLoader(MyClassLoader myLoader) { this.myLoader = myLoader; } public long getLoadTime() { return loadTime; } public void setLoadTime(long loadTime) { this.loadTime = loadTime; } public BaseManager getManager() { return manager; } public void setManager(BaseManager manager) { this.manager = manager; } }
5.編寫ManagerFactory類
package com.myimooc.classloader; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; /** * @title Manager工廠類 * @describe 加載manager的工廠 * @author zc * @version 1.0 2017-12-01 */ public class ManagerFactory { /** 記錄熱加載類的加載信息 */ private static final MaploadTimeMap = new HashMap (); /** 要加載的類的classpath路徑 */ public static final String CLASS_PATH = "D:/AllSpace/ByStudy/classloader/bin/"; /** 實現熱加載的類的全名稱(包名+類名) */ public static final String MY_MANAGER = "com.myimooc.classloader.MyManager"; public static BaseManager getManager(String className){ File loadFile = new File(CLASS_PATH + className.replaceAll(".", "/")+".class"); long lastModified = loadFile.lastModified(); if(loadTimeMap.get(className)== null){ // loadTimeMap不包含className為key的LoadInfo信息。 // 證明這個類沒有被加載,那么需要加載這個類到JVM中 load(className,lastModified); }else if(loadTimeMap.get(className).getLoadTime()!=lastModified){ // 加載類的時間戳變化了,同樣要重新加載 load(className,lastModified); } return loadTimeMap.get(className).getManager(); } private static void load(String className, long lastModified) { MyClassLoader myClassLoader = new MyClassLoader(CLASS_PATH); Class> loadClass = null; try { loadClass = myClassLoader.findClass(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } BaseManager manager = newInstance(loadClass); LoadInfo loadInfo = new LoadInfo(myClassLoader,lastModified); loadInfo.setManager(manager); loadTimeMap.put(className, loadInfo); } /** * @title 創建實例對象 * @describe 以反射的方式創建BaseManager子類對象 * @author zc * @version 1.0 2017-12-01 */ private static BaseManager newInstance(Class> loadClass) { try { return (BaseManager)loadClass.getConstructor(new Class[]{}).newInstance(new Object[]{}); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { e.printStackTrace(); } return null; } }
6.編寫MsgHandler類
package com.myimooc.classloader; /** * @title 后臺線程 * @describe 后臺啟動一條線程不斷刷新加載實現了熱加載的類 * @author zc * @version 1.0 2017-12-01 */ public class MsgHandler implements Runnable{ @Override public void run() { while(true){ BaseManager manager = ManagerFactory.getManager(ManagerFactory.MY_MANAGER); manager.logic(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
7.編寫ClassLoaderTest類
package com.myimooc.classloader; /** * @title 測試類 * @describe 測試Java類的熱加載 * @author zc * @version 1.0 2017-12-01 */ public class ClassLoaderTest { public static void main(String[] args) { new Thread(new MsgHandler()).start(); } }第四章:項目演示 4-1 簡單介紹
Spring Boot簡單介紹
是一個全新框架,目的是簡化Spring應用的搭建與開發過程 該框架開發人員不需要定義樣板化的配置 從根本上講,是一些庫的集合,構建項目,無須自行管理這些庫的版本
Spring Boot特點
創建獨立的Spring應用程序 嵌入的Tomcat,無須部署war文件 簡化Maven配置和Gradle配置 自動配置Spring 提供生產就緒功能,如指標、健康檢查和外部配置
Spring Boot使用場景
開發Restful風格的微服務架構 微服務、自動化、橫向擴展 精簡配置與整合其他工具4-2 項目搭建
創建名為hotdeploy的gradle工程build.gradle腳本如下
buildscript { ext { springBootVersion = "1.5.6.RELEASE" } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: "java" apply plugin: "eclipse" apply plugin: "org.springframework.boot" group = "com.myimooc" version = "0.0.1-SNAPSHOT" sourceCompatibility = 1.8 repositories { maven{ url "http://maven.aliyun.com/nexus/content/groups/public/"} mavenCentral() } dependencies { compile("org.springframework.boot:spring-boot-starter") compile("org.springframework.boot:spring-boot-starter-web") compile("org.springframework.boot:spring-boot-starter-data-jpa") compile("org.springframework.boot:spring-boot-starter-thymeleaf") compile("org.springframework.boot:spring-boot-devtools") compile("com.h2database:h2") testCompile("org.springframework.boot:spring-boot-starter-test") }
代碼編寫
1.編寫HotDeployApplication類
package com.myimooc.hotdeploy; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; /** * @title Spring Boot 熱啟動 * @describe 啟動類 * @author zc * @version 1.0 2017-12-01 */ @SpringBootApplication public class HotDeployApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(HotDeployApplication.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(HotDeployApplication.class); } }
2.編寫HotDeployController類
package com.myimooc.hotdeploy.web.controller; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; /** * @title 控制器 * @describe * @author zc * @version 1.0 2017-12-01 */ @Controller public class HotDeployController { // 等價于 @RequestMapping(value="/say",method=RequestMethod.GET) @GetMapping("/say") public String say(HttpServletRequest request){ request.setAttribute("say", "Hello Spring Boot!"); return "index"; } }
3.編寫index.html頁面
4-3 部署實現Index
Spring Boot熱部署實現的方式
使用Spring Loaded:1.添加依賴,2.設置JVM參數 使用spring-boot-devtools:1.添加依賴4-4 項目發布
發布方式
構建jar包,命令行運行Spring Boot程序 構建war包,發布到Tomcat第五章:課程總結 5-1 課程總結
課程總結
課程介紹 熱部署與熱加載 熱部署原理解析 Java類熱加載案例分析 Spring Boot簡單介紹 Spring Boot項目搭建 Spring Boot項目構建過程解析 Spring Boot熱部署的實現 Spring Boot發布方式
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70697.html
摘要:熱加載代表的是我們不需要重啟服務器,就能夠類檢測得到,重新生成類的字節碼文件無論是熱部署或者是熱加載都是基于類加載器來完成的。驗證階段字節碼文件不會對造成危害準備階段是會賦初始值,并不是程序中的值。 一、SpringBoot入門 今天在慕課網中看見了Spring Boot這么一個教程,這個Spring Boot作為JavaWeb的學習者肯定至少會聽過,但我是不知道他是什么玩意。 只是大...
時間:2018年04月08日星期日說明:本文部分內容均來自慕課網。@慕課網:https://www.imooc.com 教學源碼:無 學習源碼:https://github.com/zccodere/s... 第一章:課程介紹 1-1 課程介紹 課程內容 Spring Boot介紹 環境準備 第一個Spring Boot項目 多模塊項目 打包和運行 1-2 框架定位 showImg(https...
摘要:時間年月日星期日說明本文部分內容均來自慕課網。整體目錄結構如下項目文件用于數據持久化配置項目配置配置視圖解析器配置靜態資源映射配置配置配置自定義指令配置解析器配置,類似于項目啟動類新建,注冊配置類,并將其和當前關聯。 時間:2017年3月19日星期日說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:無個人學習源碼:https://githu...
摘要:慕課網發送郵件學習總結時間年月日星期六說明本文部分內容均來自慕課網。 慕課網《Spring Boot 發送郵件》學習總結 時間:2018年09月08日星期六 說明:本文部分內容均來自慕課網。@慕課網:https://www.imooc.com 教學源碼:https://github.com/ityouknow/... 學習源碼:https://github.com/zccoder...
閱讀 2202·2021-10-18 13:28
閱讀 2511·2021-10-11 10:59
閱讀 2340·2019-08-29 15:06
閱讀 1131·2019-08-26 13:54
閱讀 807·2019-08-26 13:52
閱讀 3148·2019-08-26 12:02
閱讀 2998·2019-08-26 11:44
閱讀 2511·2019-08-26 10:56