手搓spring迷你框架之旅-02 依赖注入的实现

手搓spring迷你框架之旅-02 依赖注入的实现

在上一篇的基础上实现另一个功能 自动依赖注入 也就是平常用的最多的@Autowired注解

本篇将会实现@Autowired注解 实现对bean进行自动注入

核心流程

首先 先整理一下依赖注入的流程 核心流程就是

  • BeanFactory扫描指定包路径下所有类 然后根据带@Compoent注解的类创建实例 扔到beanMap当中 (无参构造

  • 依赖注入 将beanMap中每个bean遍历 例如userservice实例 检查字段中是否带有@Autowired注解

  • 找到需要注入的字段后 会根据字段类型以及字段名 去beanMap中找到对应的实例

  • 找到后 将这个字段的值设置为找到的实例(利用反射)

操作待补 电脑丢公司了....20250325 8:49

接下来一步一步来 这里我已经写好了程序

创建注解

在Annotion包里创建我们需要的Autowired注解

package com.dms.shanshan.core.Annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}

这个注解允许被用在字段上--@Target(ElementType.FIELD)

接下来说依赖注入的逻辑

修改BeanFactory--之前的包扫描逻辑仍然不变 在此基础上 新增一个依赖注入方法injectDependcy()

这个方法有以下作用

  • 遍历beanMap当中的每个bean,然后扫描bean的字段field

  • 对于每个字段 如果字段上带有Autowired注解,就根据字段类型在beanMap当中获取相应的bean

  • 赋值给字段 实现依赖注入 不用手动创建依赖对象

上代码

   public BeanFactory(String basePackage) throws InstantiationException, IllegalAccessException {
        scanBean(basePackage);
        injectDependcy();      
    }

在beanfactory构造器中新增依赖注入方法

public void injectDependcy(){
        //扫描所有bean
        for (Object bean:beansMap.values()){
            //扫描所有bean的字段
            for (Field field:bean.getClass().getDeclaredFields()){
                if (field.isAnnotationPresent(Autowired.class)){
                    //获取字段类型
                    Class<?> fieldType=field.getType();
                    //从beanMap中获取依赖的bean
                    Object dependencyBean=beansMap.get(fieldType.getSimpleName());
                    if(dependencyBean!=null){
                        try{
                            //允许访问私有
                            field.setAccessible(true);
                            //将字段赋值
                            field.set(bean, dependencyBean);
                        }catch (Exception e){
                            System.out.println("出现错误");
                        }
                    }
                }
            }
        }

    }

依赖注入方法具体实现

这个方法比较简单 就不过多叙述 看代码即可

补充

injectDependcy()方法当中字段使用的方法解释field.setAccessible(true)field.set(bean, dependencyBean);

查看set方法源码

public void set(Object obj, Object value)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        getFieldAccessor(obj).set(obj, value);
    }

解释:

先访问检查 查看是否允许访问 如果允许 就给该对象字段设置value

第一个参数obj是需要设置值的对象字段名,第二个参数value就是这个对象的值 通过这个方法 可以给相应的bean的字段设置值

后记

仓库地址(不断更新):

https://gitee.com/du-mingshen1/hand-rubbing-spring-framework

全系列:杜明珅的手搓spring迷你框架系列

上一篇:手搓spring迷你框架之旅-01 基本结构实现

下一篇:手搓spring迷你框架之旅-03 Controller实现