亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

有關(guān)Java中的BeanInfo介紹

 更新時間:2021年09月10日 14:39:57   作者:御狐神  
Java的BeanInfo在工作中并不怎么用到,我也是在學(xué)習(xí)spring源碼的時候,發(fā)現(xiàn)SpringBoot啟動時候會設(shè)置一個屬叫"spring.beaninfo.ignore",網(wǎng)上一些地方說這個配置的意思是是否跳過java BeanInfo的搜索,但是BeanInfo又是什么呢?本文我們將對此做一個詳細(xì)介紹

1、JavaBean介紹

維基百科JavaBean的定義:JavaBeans是Java中一種特殊的類,可以將多個對象封裝到一個對象(bean)中。特點是可序列化,提供無參構(gòu)造器,提供getter方法和setter方法訪問對象的屬性。名稱中的“Bean”是用于Java的可重用軟件組件的慣用叫法。要成為JavaBean類,則必需遵循關(guān)于命名、構(gòu)造器、方法的特定規(guī)范。有了這些規(guī)范,才能有可以使用、復(fù)用、替代和連接JavaBeans的工具。規(guī)范如下:

  • 有一個public的無參數(shù)構(gòu)造器。
  • 屬性可以通過get、setis(可以替代get,用在布爾型屬性上)方法或遵循特定命名規(guī)范的其他方法訪問。
  • 可序列化。

以下為一個合法的JavaBean的定義:

public class PersonBean implements java.io.Serializable {

    /**
     * name 屬性(注意大小寫)
     */
    private String name = null;

    private boolean deceased = false;

    /** 無參構(gòu)造器(沒有參數(shù)) */
    public PersonBean() {
    }

    /**
     * name 屬性的Getter方法
     */
    public String getName() {
        return name;
    }

    /**
     * name 屬性的Setter方法
     * @param value
     */
    public void setName(final String value) {
        name = value;
    }

    /**
     * deceased 屬性的Getter方法
     * 布爾型屬性的Getter方法的不同形式(這里使用了is而非get)
     */
    public boolean isDeceased() {
        return deceased;
    }

    /**
     * deceased 屬性的Setter方法
     * @param value
     */
    public void setDeceased(final boolean value) {
        deceased = value;
    }
}

2、JavaBean的自省

用一個簡單的SpringMVC用戶登錄的場景來描述一下JavaBean的自省,用戶登錄時候,前端表單傳遞的參數(shù)通常是一個如下Json字符串:

{
 "username":"xxx",
 "password":"xxxx"
}


后端接受表單的地方,通常可以使用一個JavaBeanRequestBody的形式接收參數(shù):

public void login(@RequestBody LoginRequest request){
     // Do login
}


其中,LoginRequest類似于如下的格式:

public class LoginRequest {
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    private String username;
    private String password;
}

那么前端的Json如何映射到后端LoginRequest中的對應(yīng)屬性之上呢?可以看到LoginRequest中的字段都是private類型,無法直接設(shè)置字段值(反射雖然可以設(shè)置,但是并不合適),只能通過Setter方法進(jìn)行設(shè)置,但是程序怎么知道JavaBean有哪些Setter方法呢?此處就用到了JavaBean的內(nèi)省機(jī)制。

3、JavaBean內(nèi)省工具Introspector

Java bean的工具包中提供了java內(nèi)省工具Introspector,該工具可以通過以下方法獲取Java bean 的內(nèi)省結(jié)果BeanInfo(后文詳細(xì)介紹),獲取BeanInfo的流程如下圖所示

// 在Object類時候停止檢索,可以選擇在任意一個父類停止
BeanInfo beanInfo = Introspector.getBeanInfo(JavaBeanDemo.class,Object.class);

4、JavaBean內(nèi)省結(jié)果BeanInfo

通過java的內(nèi)省工具IntrospectorgetBeanInfo方法,我們可以獲取一個JavaBean的內(nèi)省BeanInfo,獲取到的BeanInfo包含以下屬性:

  • Bean的類相關(guān)信息
  • Bean的事件信息
  • Bean的屬性信息
  • Bean的方法信息
  • 額外屬性信息
  • Component的圖標(biāo)

5、內(nèi)省結(jié)果BeanInfo的類型

BeanInfo只是一個內(nèi)省結(jié)果的接口,Java中對該接口的實現(xiàn)有以下三種

  • ApplicationBeanInfo:Apple desktop相關(guān)的JavaBean內(nèi)省結(jié)果
  • ComponentBeanInfo:Java Awt組件的內(nèi)省結(jié)果,如按鈕等
  • GenericBeanInfo:通用的內(nèi)省結(jié)果,JEE開發(fā)中的內(nèi)省結(jié)果都為該類型

此外,Spring自定義了一個內(nèi)省結(jié)果類型,叫ExtendedBeanInfo,主要用于識別返回值不為空的Setter方法。

6、Spring的BeanUtils.copyProperties

BeanUtils.copyProperties用戶在兩個對象之間進(jìn)行屬性的復(fù)制,底層基于JavaBean的內(nèi)省機(jī)制,通過內(nèi)省得到拷貝源對象和目的對象屬性的讀方法和寫方法,然后調(diào)用對應(yīng)的方法進(jìn)行屬性的復(fù)制。以下為BeanUtils.copyProperties的流程

BeanUtilsJavaBean內(nèi)省的一些機(jī)制進(jìn)行優(yōu)化,到這里,大家有沒有發(fā)現(xiàn)Java內(nèi)省的一些缺點呢?

7、BeanUtils并發(fā)問題優(yōu)化

Java內(nèi)省的結(jié)果會緩存在ThreadGroupContext中,并且通過synchonrized關(guān)鍵字對緩存加鎖(下圖中的紅框部分),導(dǎo)致同一個線程組中的線程無法并行內(nèi)省。

SpringBeanUtils在Java內(nèi)省之上又添加了一層緩存,這層緩存使用ConcurrentHashMap實現(xiàn),從而提高了內(nèi)省的效率。

8、BeanUtils Setter屬性識別優(yōu)化

在Java默認(rèn)的內(nèi)省過程中,setter方法的返回值必須是null,如果不是null的話,無法識別為有效的JavaBean屬性(下圖中的紅色部分),Spring 自定義了一個BeanInfo ExtendedBeanInfo解決了這個問題。

回到最初提到的spring.beaninfo.ignore,這個配置用來忽略所有自定義的BeanInfo類的搜索.

9、BeanUtils 性能測試

可以看出:BeanUtils花費的時間約為直接復(fù)制的50倍以上。

public class BeanUtilsPerformanceTest {

    public static void main(String[] args){
        // 預(yù)熱虛擬機(jī)
        loopBeanUtils(100000);
        loopCopyByHand(100000);

        // 復(fù)制1萬次的情況
        System.out.println("\nloop 10000 times:");
        loopBeanUtils(10000);
        loopCopyByHand(10000);

        // 復(fù)制1百萬次的情況
        System.out.println("\nloop 1000000 times:");
        loopBeanUtils(1000000);
        loopCopyByHand(1000000);

        // 復(fù)制1億次的情況
        System.out.println("\nloop 100000000 times:");
        loopBeanUtils(100000000);
        loopCopyByHand(100000000);
    }

    private static void loopBeanUtils(int loopTimes){
        TestBeanDemo source = new TestBeanDemo();
        TestBeanDemo target = new TestBeanDemo();
        long start = System.currentTimeMillis();
        for (int i=0;i<loopTimes;i++){
            BeanUtils.copyProperties(source,target);
        }
        System.out.println("BeanUtils cost times:"+String.valueOf(System.currentTimeMillis()-start));
    }

    private static void loopCopyByHand(int loopTimes){
        TestBeanDemo source = new TestBeanDemo();
        TestBeanDemo target = new TestBeanDemo();
        long start = System.currentTimeMillis();
        for (int i=0;i<loopTimes;i++){
            target.setField1(source.getField1());
            target.setField2(source.getField2());
            target.setField3(source.getField3());
            target.setField4(source.getField4());
            target.setField5(source.getField5());
        }
        System.out.println("Copy field one by one times:"+String.valueOf(System.currentTimeMillis()-start));
    }

    @Data
    private static class TestBeanDemo{
        private String field1 = UUID.randomUUID().toString();
        private String field2 = UUID.randomUUID().toString();
        private String field3 = UUID.randomUUID().toString();
        private String field4 = UUID.randomUUID().toString();
        private String field5 = UUID.randomUUID().toString();

    }
}

到此這篇關(guān)于有關(guān)Java中的BeanInfo介紹的文章就介紹到這了,更多相關(guān)Java中的BeanInfo內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java動態(tài)設(shè)置注解值及原理詳解

    Java動態(tài)設(shè)置注解值及原理詳解

    這篇文章主要介紹了Java動態(tài)設(shè)置注解值及原理詳解,AnnotationInvocationHandler是注解的代理hander,通過反射獲取類的注解時會通過AnnotationInvocationHandler創(chuàng)建代理對象并將數(shù)據(jù)存儲到memberValues里,需要的朋友可以參考下
    2023-11-11
  • 簡單談?wù)凧ava垃圾回收

    簡單談?wù)凧ava垃圾回收

    本文是看了James Gosling的<<Java程序設(shè)計語言>>后結(jié)合自己的一些項目經(jīng)驗,簡單總結(jié)下關(guān)于java的垃圾回收問題的看法,有需要的小伙伴可以參考下
    2016-05-05
  • Linux?Ubuntu系統(tǒng)下配置JDK環(huán)境、MySQL環(huán)境全過程

    Linux?Ubuntu系統(tǒng)下配置JDK環(huán)境、MySQL環(huán)境全過程

    眾所周知Ubuntu是一種基于Linux的操作系統(tǒng),它提供了一個穩(wěn)定、安全和易于使用的環(huán)境,下面這篇文章主要給大家介紹了關(guān)于Linux?Ubuntu系統(tǒng)下配置JDK環(huán)境、MySQL環(huán)境的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • Spring?component-scan?XML配置與@ComponentScan注解配置

    Spring?component-scan?XML配置與@ComponentScan注解配置

    這篇文章主要介紹了Spring?component-scan?XML配置與@ComponentScan注解配置,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Spring Boot日志控制詳解

    Spring Boot日志控制詳解

    這篇文章主要為大家詳細(xì)介紹了Spring Boot日志控制的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Spring如何根據(jù)條件創(chuàng)建bean,@Conditional注解使用方式

    Spring如何根據(jù)條件創(chuàng)建bean,@Conditional注解使用方式

    這篇文章主要介紹了Spring如何根據(jù)條件創(chuàng)建bean,@Conditional注解使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java 實戰(zhàn)項目錘煉之樸素風(fēng)格個人博客系統(tǒng)的實現(xiàn)流程

    Java 實戰(zhàn)項目錘煉之樸素風(fēng)格個人博客系統(tǒng)的實現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java+vue+Springboot+ssm+mysql+maven+redis實現(xiàn)一個樸素風(fēng)格的個人博客系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • 手把手帶你了解Java-Stream流方法學(xué)習(xí)及總結(jié)

    手把手帶你了解Java-Stream流方法學(xué)習(xí)及總結(jié)

    這篇文章主要介紹了通過實例了解JavaStream流的方法學(xué)習(xí)和總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2021-08-08
  • Spring源碼解析之編程式事務(wù)

    Spring源碼解析之編程式事務(wù)

    今天給大家?guī)淼氖顷P(guān)于Java Spring的相關(guān)知識,文章圍繞著Spring編程式事務(wù)展開,文中有非常詳細(xì)的介紹,需要的朋友可以參考下
    2021-06-06
  • java中ArrayList和LinkedList的區(qū)別詳解

    java中ArrayList和LinkedList的區(qū)別詳解

    這篇文章主要介紹了java中ArrayList和LinkedList的區(qū)別詳解,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-01-01

最新評論