Rumah  >  Artikel  >  Java  >  Cara SpringBoot menggunakan refleksi untuk mensimulasikan IOC dan getBean

Cara SpringBoot menggunakan refleksi untuk mensimulasikan IOC dan getBean

王林
王林ke hadapan
2023-05-30 09:25:121025semak imbas

Idea asas Spring IOC

Yang kedua ialah refleksi java Mekanisme pantulan adalah teras pelaksanaan penting musim bunga Hari ini apabila saya melihat cache peringkat ketiga musim bunga untuk menyelesaikan masalah rujukan bulat kitaran hidup kacang. Ia sangat serupa dengan proses penjanaan objek Java Kemudian saya pergi ke proses penciptaan kacang dan mendapati bahawa proses mencipta contoh kacang dari awal adalah sangat menarik penggunaan pantulan dan pelbagai kaedah Struktur data peta ini merealisasikan pengeluaran saluran paip kacang, yang sangat elegan, jadi saya cuba menggunakan refleksi untuk menulis alat yang menjana objek contoh secara terbalik.

Kemudian bahagian hadapan perlu memahami proses menghasilkan objek:

Saya meringkaskan proses penciptaan objek sebagai:

Periksa sama ada terdapat rujukan simbolik kepada objek dalam kolam malar dan tentukan Sama ada ia telah melalui proses pemuatan kelas, jika tidak, proses pemuatan kelas akan dijalankan.

Peruntukkan memori untuk objek baharu (dua kaedah: perlanggaran penunjuk dan senarai bebas ) dan tetapkan W kepada 0 untuk ruang ingatan lain kecuali pengepala objek.

Tetapkan pengepala objek.

Pemulaan objek, ini ialah proses melaksanakan kaedah pembina anda dan memberikan nilai yang anda ingin tentukan kepada medan yang anda perlukan.

Tambah beberapa butiran: Dalam proses memperuntukkan memori untuk objek baharu, pertama sekali, saiz memori yang diperlukan oleh objek selepas pemuatan kelas selesai ditentukan sepenuhnya Proses memperuntukkan memori sebenarnya dalam Java heap. Bahagikan memori dengan saiz yang sama, tetapi bagaimana untuk membahagikannya? Jika susun atur memori timbunan Java diperuntukkan dalam susunan yang ketat, iaitu, satu bahagian digunakan dan satu lagi adalah percuma, maka memori akan diperuntukkan oleh perlanggaran penunjuk Apa yang dipanggil penunjuk dikumpulkan pada garis pemisah antara kawasan bebas dan kawasan yang digunakan Apabila memori diperlukan, penunjuk bergerak ke belakang sehingga panjang yang diliputi oleh pergerakan adalah sama dengan saiz memori yang diperlukan oleh objek java dan berhenti dan memperuntukkan. Tetapi bagaimana jika susun atur memori timbunan Java adalah berpecah-belah dan tidak berterusan? Kami hanya boleh mengekalkan senarai, yang merekodkan saiz dan maklumat lokasi semua kawasan bebas timbunan Java Apabila memperuntukkan, kami hanya perlu mencari peruntukan kawasan yang paling sesuai untuk objek baharu.

Keupayaan pemungut sampah dan sama ada ia boleh melakukan pemampatan ruang menentukan sama ada timbunan Java adalah tetap atau tidak. Apabila pengumpul yang kami gunakan adalah Serial dan Parnew, mereka diperuntukkan oleh perlanggaran penunjuk Apabila kami menggunakan pengumpul sampah CMS, kami perlu menggunakan peruntukan jadual kawasan percuma yang menyusahkan.

Di sini kita menumpukan pada pengisian atribut dan kaedah: jiwa objek ialah atribut dan kaedahnya:

Atribut teras yang digunakan oleh keseluruhan alat:

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

Jom lihat fungsi kaedah ini terlebih dahulu:

  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;
        }
    }

Dapatkan pembina jenis tersebut. Sila ambil perhatian bahawa ini ialah binaan tanpa parameter Jika anda tidak mempunyai binaan tanpa parameter berkemungkinan melaporkan ralat, kerana kita juga tidak tahu. Berapa banyak atribut yang ada, bukan? dengan refleksi)

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()));
        }
    }

Dapatkan atribut dan isikan nilai atribut, Atribut juga disertakan di sini.

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

Dapatkan semua kaedah untuk membentuk tatasusunan kaedah.

  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);
        }
    }

Simpan kaedah ke dalam koleksi kaedah untuk penyimpanan.

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

Kaedah penggunaan adalah dengan nama.

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

kaedah 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",&#39;女&#39;);
        Person bean = (Person) getBean(new Person(), map);
        System.out.println(bean.toString());
        System.out.println(useMethod("toString"));
    }

Kaedah ujian. Maklumat jenis adalah seperti berikut:

class Person {
    private String name;
    private Integer age;
    private Character sex;
    //无参构造绝对不能少
    public Person() {
    }
    @Override
    public String toString() {
        return "Person{" +
                "name=&#39;" + name + &#39;\&#39;&#39; +
                ", age=" + age +
                ", sex=" + sex +
                &#39;}&#39;;
    }
}

Keputusan ujian adalah seperti berikut:

Cara SpringBoot menggunakan refleksi untuk mensimulasikan IOC dan getBean

Di sini kita tidak membuat instantiate objek menggunakan Person person = new Person( );, gunakan Reflection melaksanakan instantiasi objek.

Saya akan menyenaraikan kaedah refleksi yang digunakan di dalamnya:

getDeclaredFields Dapatkan objek atribut domain

getName Dapatkan nama atribut

getType Dapatkan perkataan jenis atribut Fail kod bahagian

setAccessible(true) Tetapkan pemecahan kekerasan dan dapatkan penggunaan atribut peribadi

getDeclaredMethods Dapatkan semua tatasusunan kaedah

getClass Dapatkan fail bytecode

getConstructor mendapat pembina tanpa parameter

Atas ialah kandungan terperinci Cara SpringBoot menggunakan refleksi untuk mensimulasikan IOC dan getBean. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam