手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】【任务阶段4】

手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】【任务阶段4】

任务阶段1、2、3链接
一、实现任务阶段 1- 编写自己 Spring 容器,实现扫描包, 得到 bean 的 class 对象
二、实现任务阶段 2- 扫描将 bean 信息封装到 BeanDefinition 对象, 并放入到 Map
三、实现任务阶段 3- 初始化 bean 单例池,并完成 getBean 方法 , createBean 方法

四、实现任务阶段 4- 完成依赖注入在这里插入图片描述

说明:整个实现思路,就是参考 Spring 规范
1.定义Autowired注解,实现了该注解的属性将会被进行依赖注入(看下面代码实现)

package com.hykedu.spring.annotation;

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

/**
 * @author 程序员蛇皮
 * @version 1.0
 */
@Target({ElementType.METHOD, ElementType.FIELD,})
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}

2.编辑CodeSnakeSpringApplicationContext类,在createBean方法增加识别Autowired注解进行依赖注入的功能

//完成createBean(BeanDefinition beanDefinition)方法
private Object createBean(BeanDefinition beanDefinition, String beanName) {
    //得到Bean的clazz对象
    Class clazz = beanDefinition.getClazz();
    try {
        //使用反射得到对象实例
        Object instance = clazz.getDeclaredConstructor().newInstance();
        //依赖注入
        //1.遍历当前要创建的对象的所有字段
        for (Field declaredField : clazz.getDeclaredFields()) {
            //2.判断这个字段是否有@Autowired
            if (declaredField.isAnnotationPresent(Autowired.class)) {
                //3.得到这个字段的名字
                String name = declaredField.getName();
                System.out.println("字段名:" + name);
                //4.通过getBean()获取要组装的对象
                Object bean = getBean(name);
                //5.进行组装
                //私有属性需要进行反射暴破
                declaredField.setAccessible(true);
                declaredField.set(instance, bean);
            }
        }
        System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------");
        System.out.println("=====创建好实例=====" + instance);
        if (instance != null) {
            return instance;
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    return null;
}

3.在StudentDao类中定义hi()方法,在StudentService类中定义m1()方法,在m1()调用StudentDao类的hi()方法
StudentDao.java

package com.hykedu.spring.component;

import com.hykedu.spring.annotation.Component;

/**
 * @author 程序员蛇皮
 * @version 1.0
 */
@Component
public class StudentDao {
    public void hi() {
        System.out.println("StudentDao hi~");
    }
}

StudentService.java

package com.hykedu.spring.component;

import com.hykedu.spring.annotation.Autowired;
import com.hykedu.spring.annotation.Component;
import com.hykedu.spring.annotation.Scope;

/**
 * @author 程序员蛇皮
 * @version 1.0
 */
@Scope(value = "prototype")
@Component
public class StudentService {
    //这里我们使用自己的 @Autowired 来修饰属性
    //表示该属性,是通过容器完成依赖注入
    //我们这里实现按照名字进行组装
    @Autowired
    private StudentDao studentDao;
    public void m1(){
        studentDao.hi();
    }
}

测试方法AppMain

package com.hykedu.spring;

import com.hykedu.spring.component.StudentDao;
import com.hykedu.spring.component.StudentService;
import com.hykedu.spring.ioc.CodeSnakeSpringApplicationContext;
import com.hykedu.spring.ioc.CodeSnakeSpringConfig;

/**
 * @author 程序员蛇皮
 * @version 1.0
 */
public class AppMain {
    public static void main(String[] args) {
        CodeSnakeSpringApplicationContext codeSnakeSpringApplicationContext = new CodeSnakeSpringApplicationContext(CodeSnakeSpringConfig.class);
        StudentService studentService = (StudentService) codeSnakeSpringApplicationContext.getBean("studentService");
        studentService.m1();
        System.out.println("ok");
    }
}

测试结果:StudentService中的StudentDao对象成功地进行了依赖注入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值