時(shí)間:2017年12月01日星期五
說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com
教學(xué)源碼:無
學(xué)習(xí)源碼:https://github.com/zccodere/s...
熱部署的使用場(chǎng)景
本地調(diào)式 線上發(fā)布
熱部署的使用優(yōu)點(diǎn)
無論本地還是線上,都適用 無需重啟服務(wù)器:提高開發(fā)、調(diào)式效率、提升發(fā)布、運(yùn)維效率、降低運(yùn)維成本
前置知識(shí)
掌握J(rèn)ava語言 有一定的Spring開發(fā)經(jīng)驗(yàn) 掌握構(gòu)建Spring Boot項(xiàng)目的方法
課程提綱
原理解析 案例分析 項(xiàng)目演示 測(cè)試驗(yàn)證 發(fā)布程序 課程總結(jié)第二章:原理解析 2-1 部署加載
Java熱部署與熱加載聯(lián)系
不重啟服務(wù)器編譯或部署項(xiàng)目 基于Java的類加載器實(shí)現(xiàn)
Java熱部署與熱加載的區(qū)別
部署方式 --熱部署在服務(wù)器運(yùn)行時(shí)重新部署項(xiàng)目 --熱加載在運(yùn)行時(shí)重新加載class 實(shí)現(xiàn)原理 --熱部署直接重新加載整個(gè)應(yīng)用 --熱加載在運(yùn)行時(shí)重新加載class 使用場(chǎng)景 --熱部署更多的是在生產(chǎn)環(huán)境使用 --熱加載則更多的是在開發(fā)環(huán)境使用2-2 原理解析
Java類的加載過程
類加載的五個(gè)階段
Java類加載器特點(diǎn)
1.由AppClassLoader(系統(tǒng)類加載器)開始加載指定的類 2.類加載器將加載任務(wù)交給其父類,如果其父類找不到,再由自己去加載 3.BootstrapLoader(啟動(dòng)類加載器)是最頂級(jí)的類加載器
Java類的熱部署
類的熱加載 配置Tomcat
通過類的熱加載實(shí)現(xiàn)熱部署
通過配置Tomcat實(shí)現(xiàn)熱部署
1.直接把項(xiàng)目web文件夾放在webapps里 2.在tomcat/conf/server.xml中的第三章:案例分析 3-1 案例介紹內(nèi)部添加 標(biāo)簽 3.在%tomcat_home%/conf/Catalina/localhost中添加一個(gè)XML
寫一個(gè)Java類熱加載的實(shí)際案例,要求如下
1.類層次結(jié)構(gòu)清晰,修改某一個(gè)Java類文件不需要重啟服務(wù)或者重新編譯運(yùn)行程序 2.可適當(dāng)?shù)倪\(yùn)用一些設(shè)計(jì)模式使代碼結(jié)構(gòu)更加清晰明了,比如工廠模式等3-2 案例實(shí)現(xiàn)
創(chuàng)建名為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 來實(shí)現(xiàn)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文件中的內(nèi)容 * @describe 加載class文件中的內(nèi)容 * @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.編寫B(tài)aseManager類
package com.myimooc.classloader; /** * @title 標(biāo)識(shí)接口 * @describe 實(shí)現(xiàn)這個(gè)接口的子類需要?jiǎng)討B(tài)更新 * @author zc * @version 1.0 2017-12-01 */ public interface BaseManager { public void logic(); }
3.編寫MyManager類
package com.myimooc.classloader; /** * @title 接口實(shí)現(xiàn)類 * @describe BaseManager的子類,此類需要實(shí)現(xiàn)Java類的熱加載功能 * @author zc * @version 1.0 2017-12-01 */ public class MyManager implements BaseManager { @Override public void logic() { System.out.println("學(xué)習(xí)如何實(shí)現(xiàn)Java類的熱加載案例"); } }
4.編寫LoadInfo類
package com.myimooc.classloader; /** * @title 類加載信息 * @describe 封裝加載類的信息 * @author zc * @version 1.0 2017-12-01 */ public class LoadInfo { /** 自定義的類加載器 */ private MyClassLoader myLoader; /** 記錄要加載類的時(shí)間戳,加載的時(shí)間 */ 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/"; /** 實(shí)現(xiàn)熱加載的類的全名稱(包名+類名) */ 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信息。 // 證明這個(gè)類沒有被加載,那么需要加載這個(gè)類到JVM中 load(className,lastModified); }else if(loadTimeMap.get(className).getLoadTime()!=lastModified){ // 加載類的時(shí)間戳變化了,同樣要重新加載 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 創(chuàng)建實(shí)例對(duì)象 * @describe 以反射的方式創(chuàng)建BaseManager子類對(duì)象 * @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 后臺(tái)線程 * @describe 后臺(tái)啟動(dòng)一條線程不斷刷新加載實(shí)現(xiàn)了熱加載的類 * @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 測(cè)試類 * @describe 測(cè)試Java類的熱加載 * @author zc * @version 1.0 2017-12-01 */ public class ClassLoaderTest { public static void main(String[] args) { new Thread(new MsgHandler()).start(); } }第四章:項(xiàng)目演示 4-1 簡(jiǎn)單介紹
Spring Boot簡(jiǎn)單介紹
是一個(gè)全新框架,目的是簡(jiǎn)化Spring應(yīng)用的搭建與開發(fā)過程 該框架開發(fā)人員不需要定義樣板化的配置 從根本上講,是一些庫的集合,構(gòu)建項(xiàng)目,無須自行管理這些庫的版本
Spring Boot特點(diǎn)
創(chuàng)建獨(dú)立的Spring應(yīng)用程序 嵌入的Tomcat,無須部署war文件 簡(jiǎn)化Maven配置和Gradle配置 自動(dòng)配置Spring 提供生產(chǎn)就緒功能,如指標(biāo)、健康檢查和外部配置
Spring Boot使用場(chǎng)景
開發(fā)Restful風(fēng)格的微服務(wù)架構(gòu) 微服務(wù)、自動(dòng)化、橫向擴(kuò)展 精簡(jiǎn)配置與整合其他工具4-2 項(xiàng)目搭建
創(chuàng)建名為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 熱啟動(dòng) * @describe 啟動(dòng)類 * @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 { // 等價(jià)于 @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 部署實(shí)現(xiàn)Index
Spring Boot熱部署實(shí)現(xiàn)的方式
使用Spring Loaded:1.添加依賴,2.設(shè)置JVM參數(shù) 使用spring-boot-devtools:1.添加依賴4-4 項(xiàng)目發(fā)布
發(fā)布方式
構(gòu)建jar包,命令行運(yùn)行Spring Boot程序 構(gòu)建war包,發(fā)布到Tomcat第五章:課程總結(jié) 5-1 課程總結(jié)
課程總結(jié)
課程介紹 熱部署與熱加載 熱部署原理解析 Java類熱加載案例分析 Spring Boot簡(jiǎn)單介紹 Spring Boot項(xiàng)目搭建 Spring Boot項(xiàng)目構(gòu)建過程解析 Spring Boot熱部署的實(shí)現(xiàn) Spring Boot發(fā)布方式
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/70697.html
摘要:熱加載代表的是我們不需要重啟服務(wù)器,就能夠類檢測(cè)得到,重新生成類的字節(jié)碼文件無論是熱部署或者是熱加載都是基于類加載器來完成的。驗(yàn)證階段字節(jié)碼文件不會(huì)對(duì)造成危害準(zhǔn)備階段是會(huì)賦初始值,并不是程序中的值。 一、SpringBoot入門 今天在慕課網(wǎng)中看見了Spring Boot這么一個(gè)教程,這個(gè)Spring Boot作為JavaWeb的學(xué)習(xí)者肯定至少會(huì)聽過,但我是不知道他是什么玩意。 只是大...
時(shí)間:2018年04月08日星期日說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):https://www.imooc.com 教學(xué)源碼:無 學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:課程介紹 1-1 課程介紹 課程內(nèi)容 Spring Boot介紹 環(huán)境準(zhǔn)備 第一個(gè)Spring Boot項(xiàng)目 多模塊項(xiàng)目 打包和運(yùn)行 1-2 框架定位 showImg(https...
摘要:時(shí)間年月日星期日說明本文部分內(nèi)容均來自慕課網(wǎng)。整體目錄結(jié)構(gòu)如下項(xiàng)目文件用于數(shù)據(jù)持久化配置項(xiàng)目配置配置視圖解析器配置靜態(tài)資源映射配置配置配置自定義指令配置解析器配置,類似于項(xiàng)目啟動(dòng)類新建,注冊(cè)配置類,并將其和當(dāng)前關(guān)聯(lián)。 時(shí)間:2017年3月19日星期日說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:無個(gè)人學(xué)習(xí)源碼:https://githu...
摘要:慕課網(wǎng)發(fā)送郵件學(xué)習(xí)總結(jié)時(shí)間年月日星期六說明本文部分內(nèi)容均來自慕課網(wǎng)。 慕課網(wǎng)《Spring Boot 發(fā)送郵件》學(xué)習(xí)總結(jié) 時(shí)間:2018年09月08日星期六 說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):https://www.imooc.com 教學(xué)源碼:https://github.com/ityouknow/... 學(xué)習(xí)源碼:https://github.com/zccoder...
閱讀 2210·2021-10-18 13:28
閱讀 2522·2021-10-11 10:59
閱讀 2346·2019-08-29 15:06
閱讀 1139·2019-08-26 13:54
閱讀 816·2019-08-26 13:52
閱讀 3152·2019-08-26 12:02
閱讀 3007·2019-08-26 11:44
閱讀 2518·2019-08-26 10:56