java~通過ClassLoader動(dong)態加載類(lei),實現(xian)簡單(dan)的熱部署
熱部(bu)(bu)署一般(ban)是在開(kai)發中使用(yong),在spring里(li)一般(ban)使用(yong)devtools,springloaded等工具來實(shi)現,一般(ban)在調(diao)試項目時(shi)不需要(yao)再發布,而直(zhi)接(jie)加(jia)載變化的(de)類(lei)對象(xiang)即可(ke);而有(you)時(shi)有(you)生(sheng)產環境也(ye)需要(yao)考慮對一些jar進行熱部(bu)(bu)署。
- 說明:本方法是加載外部包里的類,然后通過反射實現,如果你引用了這個包到項目里,那本方法將失效
一個類加載器只能加載一個同名類,在Java默認的類加載器層面作了判斷,如果已經有了該類,則不再重復加載,如果強行繞過判斷并使用自定義類加載器重復加載,JVM 將會拋出 LinkageError:attempted duplicate class definition for name。
注(zhu)意:不同(tong)(tong)的類(lei)加載(zai)器(qi)是可(ke)以(yi)加載(zai)同(tong)(tong)名的類(lei)的,加載(zai)完成之后,這兩(liang)個(ge)類(lei)雖然(ran)同(tong)(tong)名,但不是同(tong)(tong)一個(ge) Class 對象,使(shi)用(yong)自定義(yi)的類(lei)加載(zai)器(qi),加載(zai)一個(ge)類(lei),當需要(yao)進行(xing)替換類(lei)的時候(hou),我們(men)就丟棄之前(qian)的類(lei)加載(zai)器(qi)和類(lei),使(shi)用(yong)新(xin)(xin)的類(lei)加載(zai)器(qi)去加載(zai)新(xin)(xin)的 Class 文件(jian),然(ran)后運行(xing)新(xin)(xin)對象的方法。
熱部署的過程

接口調用
通(tong)過一個(ge)對外的接口,進(jin)行數(shu)據的返回,主要調(diao)用了(le)HelloImpl類里(li)的password方(fang)法(fa)
/**
* 自定義類加載器.
*/
@Component
public class RsaClassLoader {
@SneakyThrows
public Class findClassLoader(String packageUrl, String name) throws ClassNotFoundException {
URL url = new URL(packageUrl);
ClassLoader loader = new URLClassLoader(new URL[]{url}) {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
try {
String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
InputStream is = getClass().getResourceAsStream(fileName);
if (is == null) {
return super.loadClass(name);
}
byte[] b = new byte[is.available()];
is.read(b);
return defineClass(name, b, 0, b.length);
} catch (IOException e) {
e.printStackTrace();
throw new ClassNotFoundException(name);
}
}
};
return loader.loadClass(name);
}
}
在接口中調這個公用類
Class clazz = rsaClassLoader.findClassLoader("file:///D:\\a-start-hot-dependency-1.0.0.jar","com.lind.hot.HelloImpl");
Object account = clazz.newInstance();
Object ret = account.getClass().getMethod("password", new Class[]{}).invoke(account);
return ResponseEntity.ok(ret);
在程(cheng)序運(yun)行時,你可以動態修改(gai)a-start-hot-dependency-1.0.0.jar這個包(bao)的(de)(de)內容(rong),來(lai)達到(dao)熱部署的(de)(de)效果(guo)!