IOC底层的实现机制-反射

目录

往userController中自动注入userService

普通反射的方式

注解的方式-未利用到set

Spring整体脉络梳理


往userController中自动注入userService

public class UserController{
   @Autowired
    private UserService userService;
}

普通反射的方式

package com.spring;

import com.spring.controller.UserController;
import com.spring.service.UserService;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class MyTest {

    //@Test
    public void test() throws Exception {
        UserController userController = new UserController();
        Class<? extends UserController> clazz = userController.getClass();

        //创建对象
        UserService userService = new UserService();
        //获取属性值
        Field serviceField = clazz.getDeclaredField("userService");
        //因为属性值是私有的,只能通过set方法和get方法设置和获取值,所以需要先拿到属性名然后拼接成对应的方法
        String name = serviceField.getName();
        //拼接方法的名称
        name = name.substring(0,1).toUpperCase() + name.substring(1, name.length());
        String setMethodName = "set" + name;
        //通过方法注入属性的对象
        Method method = clazz.getMethod(setMethodName, UserService.class);
        //反射
        method.invoke(userController, userService);
        System.out.println(userController.getUserService());

    }
}

通过一系列的反射操作将userService属性注入至userController之中。实际以上的原生代理在实际工作中都用注解进行代替。

只要获取了一个对象的class对象,就可以为这个类做随意的编写。(属性,构造器,方法啊等等)

注解的方式-未利用到set

自己实现一个@AutoWired注解

package com.spring.annotation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
@Documented
public @interface AutoWired {
}
package com.spring;

import com.spring.annotation.AutoWired;
import com.spring.controller.UserController;
import com.spring.service.UserService;

import java.util.stream.Stream;

public class MyTest2 {
    public static void main(String[] args) {
        UserController userController = new UserController();
        Class<? extends  UserController> clazz = userController.getClass();
        UserService userService = new UserService();

        //获取所有的属性值
        Stream.of(clazz.getDeclaredFields()).forEach(field -> {
            String name = field.getName();
            AutoWired annotation = field.getAnnotation(AutoWired.class);
            //表示当前属性上加了注解
            if(annotation != null){
                field.setAccessible(true);
                //获取属性的类型(userService对应的类型为UserService)
                Class<?> type = field.getType();
                //根据获取到的类型new一个实例对象
                try {
                    Object o = type.newInstance();
                    //把创建的对象注入至属性中
                    field.set(userController, o);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        });
        System.out.println(userController.getUserService());
    }
}

 和上面的代码对比,无拼接set方法的步骤,而是利用得到的属性类型创建了一个UserService对象再设置至属性中去,不是我们自己去创建的。没有用到和set相关的东西。

类似地@Value @Controller @Component @Service都可以作类似的实现

Spring整体脉络梳理

学习建议:一定要去看官网

beanFactory:一个接口,一定存在对应的实现类。

DefaultListableBeanFactory.java中存在很多的Map(可以认为IOC容器中就是创建了很多的Map集合)

 

监听器:观察者模式

总结:想要成为一个框架,首先要考虑的一定是扩展性

Spring提供了什么扩展性?

  • 在对象创建之前添加某些功能
  • 在容器初始化之前添加某些功能
  • 在不同的阶段发出不同的事件,完成一些功能
  • 抽象出一堆的接口来帮助扩展
  • 面向接口编程

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值