用Java反射(Reflection)解释Spring Boot 中依赖注入的原理

首先我们在学习原理前,需要先了解下反射

Reflection(反射)

在有些场景中,需要在运行时动态的操作类的成员,比如在运行时根据数据库中提供具体的类名或方法名,或者根据字符串来动态实例化对象或者调用方法时,就不能通过new()对象,的方式 创建类或者 是使用类中的方法了

关键思路在于创建 class对象

我们写的每一个类如下被虚拟机解析

请添加图片描述

JVM是如何创建 Class 对象的
请添加图片描述

首先通过.java 编译成 .class 文件,然后通过 Class Loader 加载到内存, 随后JVM根据内存中的信息创建响应的Class 对象。

如何获取某个类的Class 对象
  • 直接用类名.class, 就是某个类的class对象

    Class<User> userClass = User.class;
    
  • 通过对象的.getClass() 方法,我们在编译阶段无法准确地判断Class对象的确切类型

    Class<?> clazz = user.getClass(); //使用通配符
    
  • 通过Class.forName() 方法获取 类型

    Class<?> class = Class.forName("org.blcu.taco.User")
    
    • 参数为完全类的限定名
    • 通过这种方法获取类的对象时,类的静态代码块会立即执行。
某个类的Class对象的常用操作

假设我们有一个类为:

public class Son {
   
    private final String idNum;
    public String school;
    public String name;
    private static final String staticField = "Son static field"
    public Son (String idNum,String name) {
   
        this.idNum = idNum;
        this.name = name;
    }
    static {
   
        System.out.println("Son static block");
    }

    public static void sayHello() {
   
        System.out.println("Son say hello");
    }

    public void sayHi(String name) {
   
        System.out.println("Son say hi to " + name);
    }

    private static void sayBye() {
   
        System.out.println("Son sayBye");
    }

    private static void sayBye(String what) {
   
        System.out.println("Son".concat(what));
    }

    private void sayBye1() {
   
        System.out.println(this.name+"Son sayBye1");
    }

}

那当我们获取了Son 的 Class 对象后,我们能做什么操作呢?

  • 获取所有字段名

    // 获取Son类的Class对象
    Class<?> aClass = Class.forName("studydemo.reflection.Son");
    // 通过这种方法获取类的对象时,类的静态代码块会立即执行, 此时我们的静态代码块就会执行,输出:son static block
    
    
    // 获取反射类中所有的公有字段
    Field[] fields = aClass.getFields();
    for (Field field : fields) {
         
        System.out.println(field.getName());
    }
    
    // 获取所有的字段名,包括共有和私有
    Field[] declaredFields1 = aClass.getDeclaredFields();
    for (Field field : declaredFields1) {
         
        System.out.println(field.getName());
    }
    
  • 获取本类中所有的方法名

    // 获取Son类的Class对象
    Class<?> aClass = Class.forName("studydemo.reflection.Son");
    // 获取所有的方法名
    Method[] declaredMethods = aClass.getDeclaredMethods();
    for (Method declaredMethod : declaredMethods) {
         
        System.out.println(declaredMethod
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值