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

Spring之關(guān)于PropertyDescriptor的擴(kuò)展剖析

 更新時(shí)間:2023年07月07日 08:57:27   作者:StrangerIt  
這篇文章主要介紹了Spring之關(guān)于PropertyDescriptor的擴(kuò)展剖析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、jdk中類PropertyDescriptor獲取

jdk中Introspector類為工具提供了一種標(biāo)準(zhǔn)的方法來了解目標(biāo)Java Bean支持的屬性、事件和方法。

 java.beans.Introspector#getTargetPropertyInfo
	private PropertyDescriptor[] getTargetPropertyInfo() {
        // Apply some reflection to the current class.
        // First get an array of all the public methods at this level
        Method methodList[] = getPublicDeclaredMethods(beanClass);
        // Now analyze each method.
        //遍歷所有方法看是否是符合PropertyDescriptor
        for (int i = 0; i < methodList.length; i++) {
            Method method = methodList[i];
            if (method == null) {
                continue;
            }
            // skip static methods.
            int mods = method.getModifiers();
            if (Modifier.isStatic(mods)) {
                continue;
            }
            String name = method.getName();
            Class<?>[] argTypes = method.getParameterTypes();
            Class<?> resultType = method.getReturnType();
            int argCount = argTypes.length;
            PropertyDescriptor pd = null;
            if (name.length() <= 3 && !name.startsWith(IS_PREFIX)) {
                // Optimization. Don't bother with invalid propertyNames.
                continue;
            }
            try {
                if (argCount == 0) {
                    /**
                     * 方法沒有參數(shù):方法有readMethod沒有writeMehtod
                     *    1、普通get開頭方法
                     *    2、返回值boolean 以is開頭的
                     */
                    if (name.startsWith(GET_PREFIX)) {
                        // Simple getter
                        pd = new PropertyDescriptor(this.beanClass, name.substring(3), method, null);
                    } else if (resultType == boolean.class && name.startsWith(IS_PREFIX)) {
                        // Boolean getter
                        pd = new PropertyDescriptor(this.beanClass, name.substring(2), method, null);
                    }
                } else if (argCount == 1) {
                    /**
                     * 有一個(gè)參數(shù)
                     * 1、有一個(gè)參數(shù)且int類型,方法get開頭的,沒有readMethod  writeMehtod等屬性
                     * 2、沒有返回值、set方法開頭的,具有writeMethod
                     */
                    if (int.class.equals(argTypes[0]) && name.startsWith(GET_PREFIX)) {
                        pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, method, null);
                    } else if (void.class.equals(resultType) && name.startsWith(SET_PREFIX)) {
                        // Simple setter
                        pd = new PropertyDescriptor(this.beanClass, name.substring(3), null, method);
                        if (throwsException(method, PropertyVetoException.class)) {
                            pd.setConstrained(true);
                        }
                    }
                } else if (argCount == 2) {
                    /**
                     * 兩個(gè)參數(shù)
                     * 1、返回值void ,第一個(gè)參數(shù)int類型,set開頭的會(huì)生成PropertyDescriptor(注意此時(shí)沒有writeMethod)
                     */
                    if (void.class.equals(resultType) && int.class.equals(argTypes[0]) && name.startsWith(SET_PREFIX)) {
                        pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, null, method);
                        if (throwsException(method, PropertyVetoException.class)) {
                            pd.setConstrained(true);
                        }
                    }
                }
            } catch (IntrospectionException ex) {
                pd = null;
            }
            if (pd != null) {
                if (propertyChangeSource) {
                    pd.setBound(true);
                }
                addPropertyDescriptor(pd);
            }
        }
    processPropertyDescriptors();
}

總結(jié)滿足以下條件才會(huì)生成PropertyDescriptor(注意讀寫方法是否為空,spring中by_type類型注入會(huì)篩選出具有寫方法不為空的PropertyDescriptor):

1、參數(shù)個(gè)數(shù)必須2個(gè)以內(nèi)、方法不是static

2、 方法沒有參數(shù):方法有readMethod沒有writeMehtod

  • 普通get開頭方法
  • 返回值boolean 以is開頭的

3、 有一個(gè)參數(shù)

  • 有一個(gè)參數(shù)且int類型,方法get開頭的,沒有readMethod writeMehtod等屬性
  • 沒有返回值、set方法開頭的,具有writeMethod

4、兩個(gè)參數(shù)

  • 返回值void ,第一個(gè)參數(shù)int類型,set開頭的會(huì)生成PropertyDescriptor(注意此時(shí)沒有writeMethod)

綜上所述:具有寫方法的必須返回值void 且set開頭一個(gè)參數(shù)的的才有寫方法(spring中by_type類型注入會(huì)篩選出具有寫方法不為空的)

demo 具有寫方法的PropertyDescriptor演示:

//@Component
public class UserService {
    private  OrderService  orderService;
   //返回值不為void
    public  OrderService  setOrderService(OrderService orderService){
        //this.orderService=orderService;
        return orderService;
    }
    //返回值不為void
    public  OrderService  setOrderService(int  test,OrderService orderService){
        this.orderService=orderService;
        return orderService;
    }
    //返回值void 一個(gè)參數(shù)滿足要求
    public  void  setService12123(OrderService orderService1){
       System.out.println("1231"+orderService);
    }
    //返回值void 參數(shù)個(gè)數(shù)大于2不滿足
    public  void  setOrderService(int  test,OrderService orderService,StockService stockService){
        this.orderService=orderService;
    }
}
public class Test {
    public static void main(String[] args) throws IntrospectionException {
       BeanInfo beanInfo= Introspector.getBeanInfo(UserService.class);
       PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
       for(PropertyDescriptor propertyDescriptor:propertyDescriptors){
           System.out.println(propertyDescriptor.getWriteMethod());
       }
    }
}

此時(shí)滿足條件方法有g(shù)etClass(繼承父類的Object) 、setService12123會(huì)生成PropertyDescriptor且具有寫方法

存在問題

方法有返回值、且靜態(tài)的方法是不具備生成PropertyDescriptor屬性描述器,spring中

org.springframework.beans.ExtendedBeanInfo#isCandidateWriteMethod

拓展有返回值、或者static也會(huì)生成PropertyDescriptor**

滿足以下條件:

return methodName.length() > 3 && methodName.startsWith(“set”) && Modifier.isPublic(method.getModifiers()) && (!Void.TYPE.isAssignableFrom(method.getReturnType()) || Modifier.isStatic(method.getModifiers())) && (nParams == 1 || nParams == 2 && Integer.TYPE == method.getParameterTypes()[0]);

二、spring針對(duì)jdk進(jìn)行拓展

ExtendedBeanInfo對(duì)jdk不滿足的方法進(jìn)行擴(kuò)展(有返回值、static)生成PropertyDescriptor

**滿足以下條件才會(huì)生成PropertyDescriptor
? ?1、set開頭方法
? ?2、public方法
? ?3、返回值不是void或者是靜態(tài)
? ?4、參數(shù)一個(gè)或者2個(gè)(2個(gè)實(shí)話第一個(gè)參數(shù)必須為int類型)**
//1、set開頭方法
       2、public方法
       3、返回值不是void或者是靜態(tài)
       4、參數(shù)一個(gè)或者2個(gè)(2個(gè)實(shí)話第一個(gè)參數(shù)必須為int類型)
    public static boolean isCandidateWriteMethod(Method method) {
        String methodName = method.getName();
        int nParams = method.getParameterCount();
        return methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) && (!Void.TYPE.isAssignableFrom(method.getReturnType()) || Modifier.isStatic(method.getModifiers())) && (nParams == 1 || nParams == 2 && Integer.TYPE == method.getParameterTypes()[0]);
    }

三、總結(jié)

spring依賴注入(@Bean(autowire=Autowire.BY_TYPE)實(shí)話會(huì)找到該類所有PropertyDescriptor滿足條件的方法

  • 1、從jdk中Introspector中獲取
  • 2、擴(kuò)展ExtendedBeanInfo獲取

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java的靜態(tài)方法調(diào)用方式

    java的靜態(tài)方法調(diào)用方式

    這篇文章主要介紹了java的靜態(tài)方法調(diào)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java使用選擇排序法對(duì)數(shù)組排序?qū)崿F(xiàn)代碼

    Java使用選擇排序法對(duì)數(shù)組排序?qū)崿F(xiàn)代碼

    這篇文章主要介紹了Java使用選擇排序法對(duì)數(shù)組排序?qū)崿F(xiàn)代碼,需要的朋友可以參考下
    2014-02-02
  • java單機(jī)接口限流處理方案詳解

    java單機(jī)接口限流處理方案詳解

    這篇文章主要為大家詳細(xì)介紹了java單機(jī)接口限流處理方案,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • RabbitMQ使用案例詳解

    RabbitMQ使用案例詳解

    RabbitMQ是基于Erlang語(yǔ)言開發(fā)的開源的消息中間件,這篇文章給大家介紹RabbitMQ使用案例,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • shiro整合swagger的注意事項(xiàng)

    shiro整合swagger的注意事項(xiàng)

    這篇文章主要介紹了shiro整合swagger需要注意的地方,幫助大家更好的理解和學(xué)習(xí)使用shiro框架,感興趣的朋友可以了解下
    2021-05-05
  • MyBatis延遲加載實(shí)現(xiàn)步驟詳解

    MyBatis延遲加載實(shí)現(xiàn)步驟詳解

    這篇文章主要介紹了MyBatis延遲加載實(shí)現(xiàn)步驟詳解,? MyBatis中的延遲加載,也成為懶加載,是指在進(jìn)行關(guān)聯(lián)查詢時(shí),按照設(shè)置的延遲規(guī)則推遲對(duì)關(guān)聯(lián)對(duì)象的查詢,延遲加載可以有效的減少數(shù)據(jù)庫(kù)的壓力,需要的朋友可以參考下
    2023-10-10
  • 使用Java實(shí)現(xiàn)5種負(fù)載均衡算法實(shí)例

    使用Java實(shí)現(xiàn)5種負(fù)載均衡算法實(shí)例

    負(fù)載均衡指由多臺(tái)服務(wù)器以對(duì)稱的方式組成一個(gè)服務(wù)器集合,每臺(tái)服務(wù)器都具有等價(jià)的地位,都可以單獨(dú)對(duì)外提供服務(wù)而無(wú)須其他服務(wù)器的輔助,這篇文章主要給大家介紹了關(guān)于使用Java實(shí)現(xiàn)5種負(fù)載均衡算法的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • java樹結(jié)構(gòu)stream工具類的示例代碼詳解

    java樹結(jié)構(gòu)stream工具類的示例代碼詳解

    Stream 作為 Java 8 的一大亮點(diǎn),它與 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。今天通過本文重點(diǎn)給大家介紹java樹結(jié)構(gòu)stream工具類的示例代碼,感興趣的朋友一起看看吧
    2022-03-03
  • 通過實(shí)例學(xué)習(xí)Java集合框架HashSet

    通過實(shí)例學(xué)習(xí)Java集合框架HashSet

    這篇文章主要介紹了通過實(shí)例學(xué)習(xí)Java集合框架HashSet,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • SpringBoot3集成RocketMq場(chǎng)景分析

    SpringBoot3集成RocketMq場(chǎng)景分析

    RocketMQ因其架構(gòu)簡(jiǎn)單、業(yè)務(wù)功能豐富、具備極強(qiáng)可擴(kuò)展性等特點(diǎn)被廣泛應(yīng)用,比如金融業(yè)務(wù)、互聯(lián)網(wǎng)、大數(shù)據(jù)、物聯(lián)網(wǎng)等領(lǐng)域的業(yè)務(wù)場(chǎng)景,這篇文章主要介紹了SpringBoot3集成RocketMq,需要的朋友可以參考下
    2023-08-08

最新評(píng)論