最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springBoot動態(tài)加載jar及如何將類注冊到IOC

 更新時(shí)間:2024年11月05日 10:09:47   作者:又是努力搬磚的一年  
在SpringBoot項(xiàng)目中動態(tài)加載jar文件并將其類注冊到IOC容器是一種高級應(yīng)用方式,,這種方法為SpringBoot項(xiàng)目提供了更靈活的擴(kuò)展能力,使得項(xiàng)目可以在不修改原有代碼的基礎(chǔ)上增加新的功能模塊,感興趣的朋友一起看看吧

具體實(shí)現(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))){
            //逐個(gè)獲取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);
    }
}

使用:

新建一模塊,寫一個(gè)簡單類:

@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;
    }
}

建立一個(gè)公共接口,放在公共模塊,以供加載jar時(shí)候,可以獲取接口方法

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 實(shí)現(xiàn)簡單的問答功能

    springboot 整合 langchain4j 實(shí)現(xiàn)簡單的問答功能

    最近在學(xué)習(xí)langchain4j,本文將介紹如何使用langchain4j快速實(shí)現(xiàn)一個(gè)簡單的問答功能,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2025-04-04
  • Java 如何解析key為動態(tài)的json操作

    Java 如何解析key為動態(tài)的json操作

    這篇文章主要介紹了Java 如何解析key為動態(tài)的json操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • struts2開發(fā)流程及詳細(xì)配置

    struts2開發(fā)流程及詳細(xì)配置

    這篇文章主要介紹了struts2開發(fā)流程及詳細(xì)配置,步驟比較詳細(xì),具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • 解讀Java和JavaScript區(qū)別與聯(lián)系

    解讀Java和JavaScript區(qū)別與聯(lián)系

    這篇文章主要介紹了解讀Java和JavaScript區(qū)別與聯(lián)系,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(49)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(49)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-08-08
  • java設(shè)計(jì)模式之單例模式學(xué)習(xí)

    java設(shè)計(jì)模式之單例模式學(xué)習(xí)

    單例對象(Singleton)是一種常用的設(shè)計(jì)模式。在Java應(yīng)用中,單例對象能保證在一個(gè)JVM中,該對象只有一個(gè)實(shí)例存在
    2014-01-01
  • Mybatis plus 配置多數(shù)據(jù)源的實(shí)現(xiàn)示例

    Mybatis plus 配置多數(shù)據(jù)源的實(shí)現(xiàn)示例

    這篇文章主要介紹了Mybatis plus 配置多數(shù)據(jù)源的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java中的UrlDecoder 和 UrlEncoder_動力節(jié)點(diǎn)Java學(xué)院整理

    Java中的UrlDecoder 和 UrlEncoder_動力節(jié)點(diǎn)Java學(xué)院整理

    HTML 格式編碼的實(shí)用工具類。該類包含了將 String 轉(zhuǎn)換為 application/x-www-form-urlencoded MIME 格式的靜態(tài)方法。下文通過實(shí)例代碼給大家介紹Java中的UrlDecoder 和 UrlEncoder知識,感興趣的的朋友一起看看吧
    2017-07-07
  • Java命令行參數(shù)解析工具jcommander詳解

    Java命令行參數(shù)解析工具jcommander詳解

    這篇文章主要為大家介紹了Java命令行參數(shù)解析工具jcommander命令詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Java使用CompletableFuture實(shí)現(xiàn)異步編程

    Java使用CompletableFuture實(shí)現(xiàn)異步編程

    在現(xiàn)代 Java 開發(fā)中,異步編程是一項(xiàng)重要技能,而 CompletableFuture 是從 Java 8 開始提供的一個(gè)功能強(qiáng)大的工具,用于簡化異步任務(wù)的編寫和組合,本文將詳細(xì)介紹 CompletableFuture 的基本使用和一些常見的應(yīng)用場景,需要的朋友可以參考下
    2025-01-01

最新評論

甘泉县| 阳高县| 六枝特区| 龙江县| 长治市| 延津县| 孟津县| 新闻| SHOW| 东台市| 澄迈县| 林芝县| 东乌珠穆沁旗| 五河县| 扶风县| 安福县| 疏勒县| 哈尔滨市| 县级市| 桦南县| 讷河市| 修水县| 会同县| 桂东县| 乐陵市| 佳木斯市| 张家港市| 满洲里市| 承德县| 朝阳市| 黑河市| 图木舒克市| 扎兰屯市| 万源市| 石首市| 凌源市| 温宿县| 屏边| 大竹县| 合肥市| 区。|