欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springBoot動(dòng)態(tài)加載jar及如何將類(lèi)注冊(cè)到IOC

 更新時(shí)間:2024年11月05日 10:09:47   作者:又是努力搬磚的一年  
在SpringBoot項(xiàng)目中動(dòng)態(tài)加載jar文件并將其類(lèi)注冊(cè)到IOC容器是一種高級(jí)應(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;
            }
            //生成需要注冊(cè)到ioc的bean名稱(chēng)
            // clazz.getSimpleName()用于獲取表示該類(lèi)的簡(jiǎn)單名稱(chēng)(不包括包名)。簡(jiǎn)單名稱(chēng)就是類(lèi)名本身,而不帶任何修飾或包的前綴。
            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;
        }
        //是否是抽象類(lèi)
        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的流,打開(kāi)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("獲取加載類(lèi)路徑失敗");
        }
        return new ArrayList<>(classPathList);
    }
}

使用:

新建一模塊,寫(xiě)一個(gè)簡(jiǎn)單類(lèi):

@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動(dòng)態(tài)加載jar,將類(lèi)注冊(cè)到IOC的文章就介紹到這了,更多相關(guān)springBoot動(dòng)態(tài)加載jar內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java的垃圾回收機(jī)制實(shí)例分析

    Java的垃圾回收機(jī)制實(shí)例分析

    這篇文章主要介紹了Java的垃圾回收機(jī)制,結(jié)合實(shí)例形式分析了垃圾回收機(jī)制的原理及相關(guān)操作技巧,需要的朋友可以參考下
    2019-08-08
  • springboot 啟動(dòng)如何排除某些bean的注入

    springboot 啟動(dòng)如何排除某些bean的注入

    這篇文章主要介紹了springboot 啟動(dòng)如何排除某些bean的注入方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 使用Mock進(jìn)行業(yè)務(wù)邏輯層Service測(cè)試詳解

    使用Mock進(jìn)行業(yè)務(wù)邏輯層Service測(cè)試詳解

    這篇文章主要介紹了使用Mock進(jìn)行業(yè)務(wù)邏輯層Service測(cè)試詳解,mock是一種模擬對(duì)象的技術(shù),用于在測(cè)試過(guò)程中替代真實(shí)的對(duì)象,通過(guò)mock,我們可以控制被模擬對(duì)象的行為和返回值,以便進(jìn)行更加精確的測(cè)試,需要的朋友可以參考下
    2023-08-08
  • java開(kāi)發(fā)非公平鎖不可打斷源碼示例解析

    java開(kāi)發(fā)非公平鎖不可打斷源碼示例解析

    這篇文章主要為大家介紹了java開(kāi)發(fā)非公平鎖不可打斷源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • java實(shí)現(xiàn)一個(gè)簡(jiǎn)單TCPSocket聊天室功能分享

    java實(shí)現(xiàn)一個(gè)簡(jiǎn)單TCPSocket聊天室功能分享

    這篇文章主要為大家分享了java實(shí)現(xiàn)的一個(gè)簡(jiǎn)單TCPSocket聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-04-04
  • Springboot詳解整合SpringSecurity實(shí)現(xiàn)全過(guò)程

    Springboot詳解整合SpringSecurity實(shí)現(xiàn)全過(guò)程

    Spring Security基于Spring開(kāi)發(fā),項(xiàng)目中如果使用Springboot作為基礎(chǔ),配合Spring Security做權(quán)限更加方便,而Shiro需要和Spring進(jìn)行整合開(kāi)發(fā)。因此作為spring全家桶中的Spring Security在java領(lǐng)域很常用
    2022-07-07
  • 基于Mybatis實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的示例代碼

    基于Mybatis實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的示例代碼

    在當(dāng)今的互聯(lián)網(wǎng)應(yīng)用中,微服務(wù)大行其道,隨著業(yè)務(wù)的發(fā)展和擴(kuò)展,單一的數(shù)據(jù)庫(kù)無(wú)法滿(mǎn)足日益增長(zhǎng)的數(shù)據(jù)需求,本文將基于 JDK17 + Spring Boot 3 和 MyBatis 框架實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源功能,需要的朋友可以參考下
    2024-09-09
  • 詳解SpringBoot實(shí)現(xiàn)ApplicationEvent事件的監(jiān)聽(tīng)與發(fā)布

    詳解SpringBoot實(shí)現(xiàn)ApplicationEvent事件的監(jiān)聽(tīng)與發(fā)布

    這篇文章主要為大家詳細(xì)介紹了SpringBoot如何實(shí)現(xiàn)ApplicationEvent事件的監(jiān)聽(tīng)與發(fā)布,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-03-03
  • Jvm調(diào)優(yōu)和SpringBoot項(xiàng)目?jī)?yōu)化的詳細(xì)教程

    Jvm調(diào)優(yōu)和SpringBoot項(xiàng)目?jī)?yōu)化的詳細(xì)教程

    這篇文章主要介紹了Jvm調(diào)優(yōu)和SpringBoot項(xiàng)目?jī)?yōu)化,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 在Windows系統(tǒng)下安裝Thrift的方法與使用講解

    在Windows系統(tǒng)下安裝Thrift的方法與使用講解

    今天小編就為大家分享一篇關(guān)于在Windows系統(tǒng)下安裝Thrift的方法與使用講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12

最新評(píng)論