springBoot動態(tài)加載jar及如何將類注冊到IOC
具體實現(xiàn)
Service
public interface JarService {
Boolean loadJarByName(LoadJarDTO dto);
}impl:
@Service
@RequiredArgsConstructor
@Slf4j
public class JarServiceImpl implements JarService {
private final SpringContextUtil springContextUtil;
@Override
public Boolean loadJarByName(LoadJarDTO dto) {
//初始化File-加載jar所在目錄
File jarFile = new File(dto.getJarPath());
if (!jarFile.exists()){
return false;
}
List<String> loadClassList = this.getLoadClass(jarFile.getAbsolutePath());
if (CollectionUtils.isEmpty(loadClassList)){
return false;
}
//加載jar
ClassLoader classLoader = ClassLoaderUtil.getJarClassLoader(jarFile);
for (String loadClassPath : loadClassList) {
Class<?> clazz = null;
try {
clazz = classLoader.loadClass(loadClassPath);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
if(!this.isLoadClass(clazz)){
continue;
}
//生成需要注冊到ioc的bean名稱
// clazz.getSimpleName()用于獲取表示該類的簡單名稱(不包括包名)。簡單名稱就是類名本身,而不帶任何修飾或包的前綴。
String beanName = getBeanName(dto.getPreBeanName(),clazz.getSimpleName()) ;
//加載需要加載的
if (!dto.getIsOverLoad() && springContextUtil.containsBeanDefinition(beanName)){
continue;
}
if (dto.getIsOverLoad() && springContextUtil.containsBeanDefinition(beanName)){
springContextUtil.unregisterBean(beanName);
}
springContextUtil.registerBean(beanName,clazz);
}
return true;
}
private static String getBeanName(String name, String className) {
return StringUtils.uncapitalize(name) + StringUtils.capitalize(className);
}
private boolean isLoadClass(Class<?> clazz) {
if (clazz == null){
return false;
}
//是否是接口
if (clazz.isInterface()){
return false;
}
//是否是抽象類
if (Modifier.isAbstract(clazz.getModifiers())){
return false;
}
if (clazz.getAnnotation(Service.class) != null){
return true;
}
if (clazz.getAnnotation(Component.class) != null){
return true;
}
if (clazz.getAnnotation(Repository.class) != null){
return true;
}
if (clazz.getAnnotation(Configuration.class) != null){
return true;
}
return false;
}
private List<String> getLoadClass(String jarPath) {
Set<String> classPathList = new HashSet<>();
File file = new File(jarPath);
//獲取jar的流,打開jar文件
try ( JarInputStream jarInputStream = new JarInputStream(FileUtil.getInputStream(file))){
//逐個獲取jar種文件
JarEntry jarEntry = jarInputStream.getNextJarEntry();
//遍歷
while (jarEntry != null){
//獲取文件路徑
String name = jarEntry.getName();
if (name.endsWith(".class")){
String classNamePath = name.replace(".class", "").replace("/",".");
classPathList.add(classNamePath);
}
jarEntry = jarInputStream.getNextJarEntry();
}
} catch (IOException e) {
log.error(e.getMessage());
throw new RuntimeException("獲取加載類路徑失敗");
}
return new ArrayList<>(classPathList);
}
}使用:
新建一模塊,寫一個簡單類:
@Service
public class CalculateServiceImpl implements CalculateService {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int minus(int a, int b) {
return a - b;
}
}建立一個公共接口,放在公共模塊,以供加載jar時候,可以獲取接口方法
public interface CalculateService {
int add(int a,int b);
int minus(int a ,int b);
}然后 cleam-install打成jar
建立一加載使用:
@GetMapping("/calculate/{beanName}/{a}/")
private Integer calculate( @PathVariable(value = "beanName") String beanName,
@PathVariable(value = "a") Integer a, @PathVariable("b") Integer b){
return jarService.calculate(beanName,a,b);
}
@Override
public Integer calculate(String beanName, Integer a, Integer b) {
CalculateService calculateService = SpringContextUtil.getBean(getBeanName(beanName,beanName+"Impl"), CalculateService.class);
int add = calculateService.add(a, b);
return add;
}
private static String getBeanName(String name, String className) {
return StringUtils.uncapitalize(name) + StringUtils.capitalize(className);
}到此這篇關(guān)于springBoot動態(tài)加載jar,將類注冊到IOC的文章就介紹到這了,更多相關(guān)springBoot動態(tài)加載jar內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot 整合 langchain4j 實現(xiàn)簡單的問答功能
最近在學(xué)習(xí)langchain4j,本文將介紹如何使用langchain4j快速實現(xiàn)一個簡單的問答功能,結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友參考下吧2025-04-04
解讀Java和JavaScript區(qū)別與聯(lián)系
這篇文章主要介紹了解讀Java和JavaScript區(qū)別與聯(lián)系,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02
Mybatis plus 配置多數(shù)據(jù)源的實現(xiàn)示例
這篇文章主要介紹了Mybatis plus 配置多數(shù)據(jù)源的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Java中的UrlDecoder 和 UrlEncoder_動力節(jié)點Java學(xué)院整理
HTML 格式編碼的實用工具類。該類包含了將 String 轉(zhuǎn)換為 application/x-www-form-urlencoded MIME 格式的靜態(tài)方法。下文通過實例代碼給大家介紹Java中的UrlDecoder 和 UrlEncoder知識,感興趣的的朋友一起看看吧2017-07-07
Java命令行參數(shù)解析工具jcommander詳解
這篇文章主要為大家介紹了Java命令行參數(shù)解析工具jcommander命令詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09
Java使用CompletableFuture實現(xiàn)異步編程
在現(xiàn)代 Java 開發(fā)中,異步編程是一項重要技能,而 CompletableFuture 是從 Java 8 開始提供的一個功能強大的工具,用于簡化異步任務(wù)的編寫和組合,本文將詳細介紹 CompletableFuture 的基本使用和一些常見的應(yīng)用場景,需要的朋友可以參考下2025-01-01

