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

SpringBoot實(shí)現(xiàn)使用反射模擬IOC和getBean

 更新時(shí)間:2023年04月03日 10:24:31   作者:ForestSpringH  
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)使用反射模擬IOC和getBean,IOC就是spring的核心思想之一——控制反轉(zhuǎn)。這里不再贅述,看此文章即可了解

IOC就是spring的核心思想之一:控制反轉(zhuǎn)。這里不再贅述,看我的文章即可了解:

spring基礎(chǔ)思想IOC

其次就是java的反射,反射機(jī)制是spring的重要實(shí)現(xiàn)核心,今天我看spring的三級(jí)緩存解決循壞引用的問(wèn)題時(shí),發(fā)現(xiàn)一個(gè)bean的生命周期與java對(duì)象的產(chǎn)生流程具備高度相似性,接著我就去重溫了一下bean的創(chuàng)建流程,發(fā)現(xiàn)一個(gè)bean實(shí)例從無(wú)到有經(jīng)歷的過(guò)程非常有意思,spring用極其優(yōu)雅的代碼實(shí)現(xiàn)了用反射和各種map數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)了bean的流水線式生產(chǎn),非常優(yōu)雅,于是我就嘗試用反射寫(xiě)一個(gè)逆向生成實(shí)例對(duì)象的小玩意。

那么前置需要了解一個(gè)對(duì)象生成的過(guò)程:

我將對(duì)象的創(chuàng)建過(guò)程總結(jié)為:

檢查常量池是否存在該對(duì)象的符號(hào)引用并確定是否經(jīng)過(guò)類(lèi)加載過(guò)程,都沒(méi)有則進(jìn)行類(lèi)加載過(guò)程。

為新生對(duì)象分配內(nèi)存(兩種方式:指針碰撞和空閑列表<指針碰撞涉及到當(dāng)指針調(diào)動(dòng)頻繁時(shí)為了避免出現(xiàn)臟讀,采取本地線程分配緩沖TLAB的優(yōu)先分配情況>)并將除對(duì)象頭外的其他內(nèi)存空間賦值W為0。

設(shè)置對(duì)象頭。

對(duì)象的初始化,這個(gè)就是執(zhí)行你的構(gòu)造方法的過(guò)程,給你需要的字段賦值你想要定義的值。

補(bǔ)充一下其中的細(xì)節(jié):為新生對(duì)象分配內(nèi)存過(guò)程中,首先一個(gè)對(duì)象在類(lèi)加載完成后它所需要的內(nèi)存大小是完全確定的,分配內(nèi)存的過(guò)程實(shí)際上就是在java堆里劃分一塊等大的內(nèi)存給它,但是該怎么劃分呢?如果java堆的內(nèi)存布局是嚴(yán)格的順序分配,即一邊是使用過(guò)的,一邊是空閑的,那么就會(huì)采取指針碰撞的方式分配內(nèi)存,所謂的指針在空閑區(qū)與使用區(qū)的分界線處,收到內(nèi)存需求時(shí),指針向后移動(dòng)直到移動(dòng)所覆蓋的長(zhǎng)度等于java對(duì)象所需要的內(nèi)存大小時(shí)停止并進(jìn)行分配。但如果java堆的內(nèi)存布局是碎片化的不連續(xù)的呢?我們就只能維護(hù)一個(gè)列表,這個(gè)列表記錄了所有java堆空閑區(qū)的大小與位置信息,分配時(shí)只需要查找最適合新生對(duì)象的區(qū)域分配即可。

注意:java堆是否規(guī)整是由垃圾收集器的能力決定的,是否帶有空間壓縮整理的能力。當(dāng)我們采用的收集器是Serial與Parnew時(shí)是用指針碰撞的方式分配的,當(dāng)采用的是CMS垃圾收集器的時(shí)候,則是需要使用麻煩的空閑區(qū)表分配。

這里我們著重的去關(guān)注屬性與方法的填充即可:一個(gè)對(duì)象的靈魂就是它的屬性與方法:

整個(gè)工具用到的核心屬性:

    private static volatile Constructor<?> constructor;
    private static volatile Object newInstance;
    private static volatile Map<String, Method> methodMap;

我們先看看這幾個(gè)方法的作用:

  public static Constructor<?> getConstructor(Object dataType) {
        Class<?> typeClass = dataType.getClass();
        try {
            Constructor<?> constructor = typeClass.getConstructor();
            constructor.setAccessible(true);
            return constructor;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            return null;
        }
    }

獲取類(lèi)型的構(gòu)造器,注意這可是無(wú)參構(gòu)造,如果你沒(méi)有無(wú)參構(gòu)造那么很有可能報(bào)錯(cuò),因?yàn)槲覀円膊恢浪卸嗌賹傩詫?duì)吧?(時(shí)刻記住咱們是逆向?。?!不知道這個(gè)類(lèi)型里有什么?。。∫磺卸际欠瓷鋷?lái)的信息)

public static void fillValueToNewInstance(Object dataType, Map<String, Object> initialMap) throws Exception {
        constructor = getConstructor(dataType);
        Class<?> typeClass = dataType.getClass();
        Field[] declaredFields = typeClass.getDeclaredFields();
        Iterator<Field> fieldIterator = Arrays.stream(declaredFields).iterator();
        newInstance = constructor.newInstance();
        while (fieldIterator.hasNext()) {
            Field field = fieldIterator.next();
            field.setAccessible(true);
            if (initialMap != null)
                field.set(newInstance, initialMap.get(field.getName()));
        }
    }

獲取屬性并填充屬性值,這里也順帶著將屬性給進(jìn)去了。

 public static Method[] getMethodArray(Object dataType) {
        return dataType.getClass().getDeclaredMethods();
    }

獲取一切方法組成方法數(shù)組。

  public static void fillMethodMap(Object dataType) {
        methodMap = new HashMap<>();
        Method[] methodArray = getMethodArray(dataType);
        Iterator<Method> iterator = Arrays.stream(methodArray).iterator();
        while (iterator.hasNext()) {
            Method method = iterator.next();
            method.setAccessible(true);
            methodMap.put(method.getName(), method);
        }
    }

將方法存到方法集合中去存儲(chǔ)。

 public static Object useMethod(String methodName, @Nullable Object... parameters) throws Exception {
        return methodMap.get(methodName).invoke(newInstance, parameters);
    }

使用方法要通過(guò)名稱(chēng)。

    @SneakyThrows
    public static Object getBean(Object dataType, Map<String, Object> parameterMap) {
        fillValueToNewInstance(dataType, parameterMap);
        fillMethodMap(dataType);
        return newInstance;
    }

getBean方法。

  public static void main(String[] args) throws Exception {
        Map<String,Object> map = new HashMap<>();
        map.put("name","xu");
        map.put("age",Integer.valueOf(18));
        map.put("sex",'女');
        Person bean = (Person) getBean(new Person(), map);
        System.out.println(bean.toString());
        System.out.println(useMethod("toString"));
    }

測(cè)試方法。類(lèi)型信息如下:

class Person {
    private String name;
    private Integer age;
    private Character sex;
    //無(wú)參構(gòu)造絕對(duì)不能少
    public Person() {
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                '}';
    }
}

測(cè)試結(jié)果如下:

這里我們可沒(méi)有用Person person = new Person();的方式實(shí)例化對(duì)象,用反射實(shí)現(xiàn)了對(duì)象的實(shí)例化。

里面用到關(guān)于反射的方法我列下來(lái):

getDeclaredFields 獲取域?qū)傩詫?duì)象

getName 獲取屬性名稱(chēng)

getType 獲取屬性類(lèi)型的字節(jié)碼文件

setAccessible(true) 設(shè)置暴力破解,獲取對(duì)私有屬性的使用

getDeclaredMethods 獲取全部方法數(shù)組

getClass 獲取字節(jié)碼文件

getConstructor 獲取無(wú)參構(gòu)造器

到此這篇關(guān)于SpringBoot實(shí)現(xiàn)使用反射模擬IOC和getBean的文章就介紹到這了,更多相關(guān)SpringBoot反射模擬IOC與getBean內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springsecurity實(shí)現(xiàn)用戶登錄認(rèn)證快速使用示例代碼(前后端分離項(xiàng)目)

    springsecurity實(shí)現(xiàn)用戶登錄認(rèn)證快速使用示例代碼(前后端分離項(xiàng)目)

    這篇文章主要介紹了springsecurity實(shí)現(xiàn)用戶登錄認(rèn)證快速使用示例代碼(前后端分離項(xiàng)目),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-03-03
  • SpringBoot中@KafkaListener使用${}動(dòng)態(tài)指定topic問(wèn)題

    SpringBoot中@KafkaListener使用${}動(dòng)態(tài)指定topic問(wèn)題

    在SpringKafka中,使用${}引用Spring屬性配置,可以在不同環(huán)境中重新配置topic名稱(chēng),而無(wú)需修改代碼,在application.properties或application.yml中定義topic名稱(chēng),并在代碼中使用${}引用
    2024-12-12
  • Springboot2.1.6集成activiti7出現(xiàn)登錄驗(yàn)證的實(shí)現(xiàn)

    Springboot2.1.6集成activiti7出現(xiàn)登錄驗(yàn)證的實(shí)現(xiàn)

    這篇文章主要介紹了Springboot2.1.6集成activiti7出現(xiàn)登錄驗(yàn)證的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 詳解Spring Batch 輕量級(jí)批處理框架實(shí)踐

    詳解Spring Batch 輕量級(jí)批處理框架實(shí)踐

    這篇文章主要介紹了詳解Spring Batch 輕量級(jí)批處理框架實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Java 關(guān)系運(yùn)算符詳情及案例(下)

    Java 關(guān)系運(yùn)算符詳情及案例(下)

    這篇文章主要介紹了Java 關(guān)系運(yùn)算符詳情及案例的實(shí)現(xiàn),主要續(xù)上篇文章,上一篇文章我們講到“等于”運(yùn)算符 (==)、“不等于”運(yùn)算符(!=)、“大于”運(yùn)算符(>) ,這篇文章繼續(xù)給大家講解相關(guān)知識(shí),需要的朋友可以參考一下
    2021-12-12
  • Java中CyclicBarrier?循環(huán)屏障

    Java中CyclicBarrier?循環(huán)屏障

    這篇文章主要介紹了Java中CyclicBarrier?循環(huán)屏障,可以實(shí)現(xiàn)讓一組線程等待至某個(gè)狀態(tài)屏障點(diǎn)之后再全部同時(shí)執(zhí)行,下面文章分享CyclicBarrier循環(huán)屏障的原理,需要的小伙伴可以參考一下
    2022-05-05
  • Java四種訪問(wèn)控制修飾符知識(shí)點(diǎn)總結(jié)

    Java四種訪問(wèn)控制修飾符知識(shí)點(diǎn)總結(jié)

    本篇文章給大家詳細(xì)分析了Java四種訪問(wèn)控制修飾符的相關(guān)知識(shí)點(diǎn),有興趣的朋友可以參考學(xué)習(xí)下。
    2018-03-03
  • Springcloud Alibaba超詳細(xì)使用詳解

    Springcloud Alibaba超詳細(xì)使用詳解

    SpringCloudAlibaba是一款優(yōu)秀的微服務(wù)架構(gòu),在市面上有著廣泛的應(yīng)用,這篇文章介紹了SpringCloudAlibaba的一些基本使用,適合初學(xué)者,希望能夠給大家?guī)?lái)幫助
    2024-08-08
  • idea生成WebServices接口的完整流程步驟

    idea生成WebServices接口的完整流程步驟

    因?yàn)楣ぷ餍枰?數(shù)據(jù)傳輸部分需要使用webservice實(shí)現(xiàn),經(jīng)過(guò)兩天的研究,實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的例子,這篇文章主要給大家介紹了關(guān)于idea生成WebServices接口的完整流程步驟,需要的朋友可以參考下
    2024-08-08
  • Eclipse+Java+Swing+Mysql實(shí)現(xiàn)工資管理系統(tǒng)

    Eclipse+Java+Swing+Mysql實(shí)現(xiàn)工資管理系統(tǒng)

    這篇文章主要介紹了Eclipse+Java+Swing+Mysql實(shí)現(xiàn)工資管理系統(tǒng),對(duì)正在工作或者學(xué)習(xí)的你有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-01-01

最新評(píng)論

珲春市| 富裕县| 太白县| 澄迈县| 铜川市| 琼海市| 香港 | 甘谷县| 西平县| 南宁市| 安康市| 贞丰县| 唐河县| 乌鲁木齐市| 大同市| 澜沧| 大邑县| 金塔县| 浦县| 唐山市| 东莞市| 兰西县| 高陵县| 满洲里市| 长岛县| 华亭县| 河津市| 花垣县| 绥滨县| 荆州市| 凤山县| 大方县| 嘉义县| 阳原县| 泽州县| 循化| 凤冈县| 安丘市| 古田县| 乐平市| 怀化市|