古い新人-「mybatisソースコードの読み取り-」リフレクションモジュール

正直なところ、7年間働いている年配の女性プログラマーとして、私はソースコードを見たことがありません。未来の混乱によって強制されます。現状を変えたい。これまでの仕事とは違うことをしたいです。

ソースコードの出発点を見て、大神のコードがどのように書かれているかを知りたいし、他の人の考えを知りたいです。次に、それが自分自身であるかどうかを考えます。

トレーニングスクールの教師は、csdnは開発者がコミュニケーションをとるのに最適なWeb​​サイトであると語っています。ここに、私の啓蒙と学習のウェブサイトがあります。旗を立てました。使用しているソースコードを更新したいアップデートが完了する前にキャリアを変えるかもしれませんが、何かしたいだけです。

誰にも証明しないでください。うまく始めて終わりたいだけです。過去のアカウントを持っています。何かをエクスポートして決済できることがわかりました。

1つ:以下はmybatisパッケージのディレクトリです。今日の主人公はリフレクションパッケージです。

2:このリフレクションパッケージ、私は見下ろします、最も重要なのは次のカテゴリです、私は主要な方法をリストしました。リフレクターリフレクターは、反射を処理する最下層です。この図の方法は、最も完全なものではありません。キー列のみを選択します。

 

上の図からわかります。MetaObjectの制御は、基本的にObjectWrapperに渡されて制御されます。ObjectWrapperのクラスの制御は、MetaClassクラスに依存し、MetaClassクラスはReflectorFactoryとReflectorに依存します。

上記は最も単純な属性です。属性が次のような場合、単語のセグメンテーションが実行され、上記のgetValueとsetValueが再帰ループに入ります。自分でテストできます。

 @Test
  void shouldGetAndSetNestedProperty() {
    RichType rich = new RichType();
    MetaObject meta = SystemMetaObject.forObject(rich);
    meta.setValue("richType.richProperty", "foo");
    assertEquals("foo", meta.getValue("richType.richProperty"));
  }
三: MetaObject 对象的 setValue 和 getValue 里面用了递归,递归的控制是由分词器PropertyTokenizer 来控制结束的。里面有单测类,强烈建议运行下单测看数据。就能理解我为啥说setValue 难。为啥麻烦。

トークナイザーPropertyTokenizerは、リフレクションパケットに現れる可能性が特に高くなります。

4:PropertyTokenizer分析は、次の図に示すとおりです。

 

5:今日は分析の最初の日です。初めて読んだのですが、7、8レベルは理解できるかもしれませんが、表現が鮮やかではないかもしれません。うまく書けないなら許してください。以下では、単一のテストと段階的な注釈付きソースコードを使用しています

恥ずかしいことに、この記事ではコードパッケージは許可されていません。コードをリソースファイルに入れました。ポイントなしでリソースファイルをダウンロードできます。https://download.csdn.net/download/lileronglilerong/15120273

6:追加のサプリメント

a:上記のコードを見ると、理解できない文章に遭遇しました。自分で理解してください。機能について

package com.llr.reflect.test;

import java.util.function.Function;

public class FunctionTest {
    public static void main(String[] args) {
        String s="1234";
       /* method(s,(String inputValue)->{
            return  Integer.parseInt(inputValue);
        });*/
       // 这个写法和上面的是一样的
        method(s, Integer::parseInt);
        /**
         *    Reflector::new 等价于下面的表达式
         *    Function<Class,Reflector> function=input->new Reflector(input);
         */
    }

    public static void method(String s, Function<String,Integer> function){
        Integer i=function.apply(s);
        System.out.println(i);
    }
}

b:computeIfAbsent和isAssignableFrom

package com.llr.reflect.test;

import java.util.HashMap;

public class MapTest {
    public static void main(String[] args) {
        /**
         * 1: computeIfAbsent的方法
         * computeIfAbsent的方法有两个参数 第一个是所选map的key,第二个是需要做的操作。这个方法当key值不存在时才起作用
         */
        HashMap map=new HashMap();
        // java8之前。从map中根据key获取value操作可能会有下面的操作
        Object value = map.get("key");
        if (value == null) {
            value = new Object();
            map.put("key", value);
        }
        // java8之后。上面的操作可以简化为一行,若key对应的value为空,会将第二个参数的返回值存入并返回
        Object key2 = map.computeIfAbsent("key", k -> new Object());


        /**
         * 2:isAssignableFrom (is Assignable(可分配))    instanceof
         *
         * ClassA.isAssignableFrom(ClassB); 表示ClassA是ClassB父类就返回true,否则返回false
         *
         *  父类.class.isAssignableFrom(子类.class)
         *  子类实例 instanceof 父类类型
         */
    }
}

c:例は何ですか?

package com.llr.reflect.test;

public class BaseTest {
    public static void main(String[] args) {
        /**
         * 1: 什么是java的实例,什么是引用,什么是引用地址,什么是内存地址。
         *
         * Cat c 的意思是,在内存中分配一个变量,名字叫c,这个变量是Cat类型的
         *
         * new Cat(); 说明 new这个Cat类的一个对象,程序运行的时候,会调用构造方法Cat(),等这个构造方法执行完了,这个Cat类型的对象也就造出来了,真正的出现在内存当中了
         *
         * c就是引用,不是对象!我们new出来的这个东西,真正在内存中的这个东西叫做对象,叫做实例.
         */
        Cat c = new Cat();
        /**
         *
         * 2: 单例模式 和 静态方法。
         *
         * 这个怎么区分,如何进行使用。
         *
         * 目标:
         * a: 弄明白什么是单例模式,什么是 静态方法。
         * b: 弄明白二者的区别。
         * c: 弄明白适合的场景
         *
         * 静态方法和非静态方法:
         * 一: 静态方法和非静态方法。他们都是在第一次加载后就常驻内存
         * 二:
         * 在内存中的区别,非静态方法,创建实例对象的时候,因为属性的值对于每个对象不同,故new一个实例的时候,会把
         * 实例属性在GC heap 里copy一份,同时这个new出来的对象放在堆栈上,堆栈指针指向了刚才拷贝的那一份实例的内存地址上。
         * 而静态方法不需要。因为静态方法里面的静态字段,就是保存再 method table 里的,就只有一份。
         *
         * 三: 早期几乎所有方法都是“静态方法”,引入实例化方法概念是面向对象概念出险以后的事情。
         *
         * 结论:静态方法和实例方法是为了解决模式问题。 如果一个方法和他所在类的实例对象无关,那么他应该是静态的。否则应该是非静态的,像工具类,一般都是静态的
         *
         * 为什么使用单例模式而不用静态方法?
         * 如果一个方法和他所在类的实例对象无关,那么他应该是静态的,反之他就应该是非静态的,如果我们确实应该使用非静态的
         * 方法,但是在创建类时又确实只需要维护一份实例时,就需要用单例模式。
         *
         */
    }

    static class Cat{
        public Cat() {
        }
    }
}

d:

Classクラスにはいくつかのメソッドがあり、Methodクラスにはいくつかのメソッドがあります。ParamNameUtilメソッドを見ると、最初に発見しました

Executable 类是 :方法和Constructor的共同功能的共享超类 
package com.llr.reflect.test;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;

public class MethodTest {
    public static void main(String[] args) {

        try {
            /**
             * 1:  Class 类中的 区别是什么:getMethod,getDeclaredMethod
             */
            Class studentClass = Student.class;
            // Member  接口中的 PUBLIC和 DECLARED就有对应的描述
            // getMethod 返回所有公用的(public) 包括继承的, 如果 getName 给的是private的话,是会报错的。
            Method getNameMethod = studentClass.getMethod("getName");
            // getDeclaredMethod 返回包括公用的,私有的,默认的,但是不包括继承的
            Method setNameMethod = studentClass.getDeclaredMethod("setName", String.class);
            System.out.println(getNameMethod.getName());
            System.out.println(setNameMethod.getName());

            /**
             *
             * 2:  getDeclaringClass 和 getClass区别
             * getDeclaringClass
             * 返回的是 (返回 类表示声明该对象表示的可执行的类或接口对象。 )
             * class com.llr.reflect.test.MethodTest$Student
             *
             * getClass: (返回此Object的运行时类。 返回的类对象是被表示类的static synchronized方法锁定的对象。 )
             * 返回的是:class java.lang.reflect.Method
             */
            System.out.println("+++++++++++++++++");
            System.out.println(getNameMethod.getDeclaringClass());
            System.out.println(getNameMethod.getClass());

            /**
             * 3: getParameterTypes和getGenericParameterTypes区别
             *
             * getParameterTypes 无法取到对象中是泛型的结构化参数。 setAgeList:List
             * getGenericParameterTypes 可以取到对象中泛型的结构化参数。 setAgeList:java.util.List<java.lang.Integer>
             *
             */
            System.out.println("+++++++++++++++++");
            Method[] methods = studentClass.getMethods();
            Arrays.stream(methods).forEach(method -> {
                Class[] pType = method.getParameterTypes();
                Type[] gPType = method.getGenericParameterTypes();
                if (method.getName().contains("setAgeList")) {
                    for (Class aClass : pType) {
                        System.out.println(method.getName() + ":" + aClass.getSimpleName());
                    }
                    for (Type type : gPType) {
                        System.out.println(method.getName() + ":" + type.getTypeName());
                    }
                }
            });
            System.out.println("+++++++++++++++++");

            /**
             * 2: Method   中的getGenericReturnType和getType的区别,
             *
             * Class 实现了 Type 接口。Type 是更上层的接口
             *
             * getType 输出 class java.lang.Object,而 getGenericType 输出的是 T。
             *
             * 如果 getGenericSignature 不为空,即如果当前类型是泛型,则返回泛型类型,反之返回 getType() 的值
             */
            Class getAge = ReturnTypeTest.class.getDeclaredFields()[0].getType();
            Type getGenericAge = ReturnTypeTest.class.getDeclaredFields()[0].getGenericType();
            System.out.println(getAge.getSimpleName());
            System.out.println(getGenericAge.getTypeName());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }


    static class Student {
        private String name;
        private List<Integer> ageList;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public List<Integer> getAgeList() {
            return ageList;
        }

        public void setAgeList(List<Integer> ageList) {
            this.ageList = ageList;
        }
    }

    static class ReturnTypeTest<T> {
        T ageInfo;
    }
}

 

おすすめ

転載: blog.csdn.net/lileronglilerong/article/details/113744229