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

淺談Spring6中的反射機制

 更新時間:2023年05月17日 08:37:58   作者:@每天都要敲代碼  
Java反射機制是Java語言中一種動態(tài)(運行時)訪問、檢測、修改它本身的能力,主要作用是動態(tài)(運行時)獲取類的完整結(jié)構(gòu)信息、調(diào)用對象的方法,需要的朋友可以參考下

一:回顧反射機制

這種重點回顧一下反射Method!

為什么要回顧反射機制呢?因為我們后面要手寫一個簡易的Spring框架,便于我們理解其中的核心原理!

1. 分析方法四要素

我們先來看一下,不使用反射機制調(diào)用一個方法需要幾個要素的參與!

定義一個SomeService方法

package com.bjpowernode.reflect;
public class SomeService {
    // 沒有參數(shù)、沒有返回值的方法
    public void doSome(){
        System.out.println("public void doSome()執(zhí)行。");
    }
    // 一個參數(shù),返回String的方法
    public String doSome(String s){
        System.out.println("public String doSome(String s)執(zhí)行。");
        return s;
    }
    // 兩個參數(shù),返回String的方法
    public String doSome(String s, int i){
        System.out.println("public String doSome(String s, int i)執(zhí)行。");
        return s + i;
    }
}

進(jìn)行測試,分析方法的要素

package com.bjpowernode.reflect;
public class Test {
    public static void main(String[] args) {
        // 不使用反射機制調(diào)用這些方法
        SomeService someService = new SomeService();
        // 無參數(shù)
        someService.doSome();
        // 一個參數(shù)
        String s1 = someService.doSome("張三");
        System.out.println(s1);
        // 兩個參數(shù)
        String s2 = someService.doSome("李四", 250);
        System.out.println(s2);
    }
}

通過以上測試代碼,我們可以得出調(diào)用一個方法,一般涉及到4個要素:

①調(diào)用哪個對象的(SomeService)

②哪個方法(doSome)

③傳什么參數(shù)("張三")

④返回什么值(String類型)

總結(jié):調(diào)用哪個對象哪個方法?傳什么值?返回什么值?

2. 獲取Method

要使用反射機制調(diào)用一個方法,首先你要獲取到這個方法。

在反射機制中Method實例代表的是一個方法,那么怎么獲取Method實例呢?

編寫測試

(1)要想調(diào)用方法,首先我們要先獲取對應(yīng)的類,使用Class.forName,參數(shù)是全限定類名

(2)然后調(diào)用這個類的getDeclaredMethod方法,參數(shù)一個是方法名、另一個參數(shù)是可變可變長度參數(shù),類型是class;這樣就能獲取到方法。

(3)方法獲取到,我們就可以調(diào)用invoke(調(diào)用)方法,參數(shù)一個是obj,就是要把對象傳過來,所以我們就需要先創(chuàng)建一個對象、另一個參數(shù)也是可變長度參數(shù),傳具體的值。

例如以下程序的四要素:調(diào)用哪個對象、哪個方法、傳什么參數(shù)、返回什么值?

①obj 要素:哪個對象

②doSomeMethod 要素:哪個方法

③"李四", 250 要素:傳什么參數(shù)

④retValue 要素:返回什么值

package com.bjpowernode.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Test2 {
    public static void main(String[] args) throws Exception{
        // 使用反射機制調(diào)用方法
        // 第一步:獲取類
        Class<?> clazz = Class.forName("com.bjpowernode.reflect.SomeService");
        // 第二步:獲取方法
        Method doSomeMethod = clazz.getDeclaredMethod("doSome", String.class, int.class);
        // 第三步:調(diào)用方法,四要素
        // 創(chuàng)建對象
        Object obj = clazz.newInstance(); // 這個方法已經(jīng)過時,也可以采用其它方式
        // 也可以先獲取到無參數(shù)構(gòu)造方法,然后在創(chuàng)建對象
        Constructor<?> declaredConstructor = clazz.getDeclaredConstructor();
        Object obj1 = declaredConstructor.newInstance();
        // 調(diào)用invoke方法
        Object retValue = doSomeMethod.invoke(obj, "李四", 250);
        System.out.println(retValue);
    }
}

3. SpringDI核心實現(xiàn)原理

我們在看一下下面這種需求,假設(shè)你現(xiàn)在已知以下信息: ①有這樣一個類,類名叫做:com.powernode.reflect.User ②這個類符合javabean規(guī)范。屬性私有化,對外提供公開的setter和getter方法。 ③你還知道這個類當(dāng)中有一個屬性,屬性的名字叫做 age ④并且你還知道age屬性的類型是int類型。要求:請使用反射機制調(diào)用set方法,給User對象的age屬性賦值!

User類

package com.bjpowernode.reflect;
public class User {
    private String name;
    private int age;
    public User() {
    }
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

使用反射機制進(jìn)行賦值,通用代碼

第一步:還是通過反射機制先獲取類,Class.forName

第二步:調(diào)用getDeclaredMethod方法獲取方法,參數(shù)有兩個,怎么樣動態(tài)獲取呢?

①已知了屬性名是age,又符合javabean規(guī)范,所以我們可以動態(tài)拼接出方法名:先拼接上“set”,再調(diào)用toUpperCase方法全部轉(zhuǎn)換成大寫,然后調(diào)用charAt方法截取第一個字符;最后在調(diào)用substring方法拼接上后面的字符串;得到完整的方法名:getAge

②已知了屬性名是age,調(diào)用類的getDeclaredField方法,參數(shù)是屬性名age,就可以獲取對應(yīng)的屬性類型,但是我們需要的是.class,所以在調(diào)用參數(shù)類型的getType方法;得到完整的屬性類型(.class形式):int.class

第三步:最后就可以創(chuàng)建對象,調(diào)用invoke方法,給屬性賦值,這個方法沒有返回值類型,所以什么都不要返回;最后輸出這個對象即可!

package com.bjpowernode.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Locale;
public class Test4 {
    public static void main(String[] args) throws Exception {
        // 已知類名和屬性名
        String className = "com.bjpowernode.reflect.User";
        String propertyName = "age";
        // 使用反射機制,給age屬性賦值
        // 第一步:獲取類
        Class<?> clazz = Class.forName(className);
        // 第二步:獲取方法
        // 根據(jù)屬性獲取方法名---字符串拼接
        String setMethodName = "set"+propertyName.toUpperCase().charAt(0)+propertyName.substring(1);
        // 根據(jù)屬性獲取屬性的類型
        Field filedType = clazz.getDeclaredField(propertyName);
        // 獲取方法
        Method setMethod = clazz.getDeclaredMethod(setMethodName, filedType.getType());
        // 第三步:調(diào)用
        // 創(chuàng)建對象
        Object obj = clazz.newInstance();
        setMethod.invoke(obj,18); // 沒有返回值類型
        // 輸出打印這個對象
        System.out.println(obj);
    }
}

執(zhí)行結(jié)果:age屬性成功賦值 

看到這里我們是不是想到了Spring容器的注入?我們在看一下我們配置的spring.xml文件,就是指定了類名和屬性名;然后底層通過反射機制進(jìn)行了對象的創(chuàng)建!

 總結(jié):有了上面我們對反射機制的回顧學(xué)習(xí),后面我們就嘗試手寫一個簡易的Spring框架!

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

相關(guān)文章

  • 你知道Spring中為何不建議使用字段注入嗎

    你知道Spring中為何不建議使用字段注入嗎

    這篇文章主要給大家介紹了關(guān)于Spring中為何不建議使用字段注入的相關(guān)資料,通過本文你將對Spring的引入方式有更一步的了解,需要的朋友可以參考下
    2021-08-08
  • 簡單講解在Java編程中實現(xiàn)設(shè)計模式中的單例模式結(jié)構(gòu)

    簡單講解在Java編程中實現(xiàn)設(shè)計模式中的單例模式結(jié)構(gòu)

    這篇文章主要介紹了簡單講解在Java編程中實現(xiàn)設(shè)計模式中的單例模式結(jié)構(gòu),設(shè)計模式是最基本直白簡單的一種設(shè)計模式,需要的朋友可以參考下
    2016-04-04
  • JVM分析之類加載機制詳解

    JVM分析之類加載機制詳解

    JVM內(nèi)部架構(gòu)包含類加載器、內(nèi)存區(qū)域、執(zhí)行引擎等。日常開發(fā)中,我們編寫的java文件被編譯成class文件后,jvm會進(jìn)行加載并運行使用類。本次將對JVM加載部分進(jìn)行分析,便于大家了解并掌握加載機制
    2022-08-08
  • Java?輸入輸出?IO?NIO?AIO三兄弟對比分析對比分析

    Java?輸入輸出?IO?NIO?AIO三兄弟對比分析對比分析

    這篇文章主要為大家介紹了Java?輸入輸出?IO?NIO?AIO三兄弟對比分析對比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • SpringCloud?OpenFeign概述與使用教程

    SpringCloud?OpenFeign概述與使用教程

    OpenFeign源于Netflix的Feign,是http通信的客戶端。屏蔽了網(wǎng)絡(luò)通信的細(xì)節(jié),直接面向接口的方式開發(fā),讓開發(fā)者感知不到網(wǎng)絡(luò)通信細(xì)節(jié)。所有遠(yuǎn)程調(diào)用,都像調(diào)用本地方法一樣完成
    2023-02-02
  • idea 打包的jar運行報

    idea 打包的jar運行報 "XXX中沒有主清單屬性"

    這篇文章主要介紹了idea 打包的jar運行報 "XXX中沒有主清單屬性",文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Java控制臺實現(xiàn)猜拳游戲小游戲

    Java控制臺實現(xiàn)猜拳游戲小游戲

    這篇文章主要為大家詳細(xì)介紹了Java控制臺實現(xiàn)猜拳游戲小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Spring @Transaction 注解執(zhí)行事務(wù)的流程

    Spring @Transaction 注解執(zhí)行事務(wù)的流程

    這篇文章主要介紹了Spring @Transaction 注解執(zhí)行事務(wù)的流程,Spring 是如何開啟事務(wù)的?又是如何進(jìn)行提交事務(wù)和關(guān)閉事務(wù)的,本文給大家詳細(xì)介紹,需要的朋友可以參考下
    2021-06-06
  • springboot多租戶設(shè)計過程圖解

    springboot多租戶設(shè)計過程圖解

    這篇文章主要介紹了springboot多租戶設(shè)計過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • Java設(shè)計模式之策略模式

    Java設(shè)計模式之策略模式

    這篇文章介紹了Java設(shè)計模式之策略模式,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-10-10

最新評論