从头开始实现一个小型spring框架——实现Bean管理 IOC与DI(解决循环依赖)

写在前面

最近学习了一下spring的相关内容,所以也就想要照猫画虎地记录一下spring的框架,通过阅读这些也希望能够消除对Spring框架的恐惧,其实细心阅读也很容易理解。

项目的源码我放在了github上:源码地址

我会在这里整理文章的系列目录:

  1. 从头开始实现一个小型spring框架——手写Spring之实现SpringBoot启动
  2. 从头开始实现一个小型spring框架——手写Spring之集成Tomcat服务器
  3. 从头开始实现一个小型spring框架——控制器controller的实现
  4. 从头开始实现一个小型spring框架——实现Bean管理(IOC与DI)

一、bean管理

1.1 什么是bean?

  • bean是spring抽象出的概念
    区别于普通的对象,bean的声明周期一般较长。
  • 在整个虚拟机中都是可见的
    普通的对象仅在当前类可见,在其他类中是引用不到的。因此对bean的维护成本要高于对普通对象的维护。
  • bean一般单例存在
    正因为对bean的维护成本很高,因此bean单例存在。

1.2 bean优势

  • 运行期效率高
    bean在项目启动时初始化,使用时直接获取,提高了获取对象的性能;也减少了代码在维护上成本;减少了对象使用过后被抛弃的情况,降低虚拟机在gc时的压力。
  • 统一维护,便于管理和拓展
    不必处理链式的依赖
  • 单例存在

二、依赖注入和控制反转

很多人认为控制反转和依赖注入是相同的,其实这是一个误区。

2.1 控制反转

IOC(Inversion of Control):思想
控制反转是一种设计的原则和思想,用来降低代码之间的耦合度。

2.2 依赖注入

DI(Dependency Injection):方式
依赖注入是实现IOC的一种方式。
采用依赖注入的方式,类A中只需要定义一个B的属性,不需要通过new来获取对象,二是通过bean容器将对象new出来,并注入到A对象的引用里。

控制正转方式:

控制反转创建的方式:

三、实现

因为我们已经在上一篇文章中实现了包扫描,所以可以非常方便获取到类的信息。
获取到类的信息后,我们就要根据是否存在需要注入的依赖来实例化 Bean对象了,我们来看具体的实现:

3.1 包结构的改变

直接看下图

更改后的内容添加了对依赖注入的实现,具体有

framework模块:

  • beans包下增加
    • Autowired自定义注解:用于标记需要进行注入的域
    • Bean自定义注解:标记类为需要实例化的Bean
      test模块
  • service包增加
    • UserService :实现到controller的注入

3.2 具体实现

framework模块

Autowired标记注解

package com.qcby.beans;

import java.lang.annotation.*;

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

Bean注解

package com.qcby.beans;

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Bean {
   
}

BeanFactory工厂

这是本次实现的核心代码,将Bean通过map的形式进行保存,提供getBean,initBean方法对Bean容器内的实例进行获取和初始化Bean容器

package com.qcby.beans;

import com.qcby.web.mvc.Controller;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author kevinlyz
 * @ClassName BeanFactory
 * @Description bean工厂
 * @Date 2019-06-09 11:09
 **/
public class BeanFactory {
   

    //ConcurrentHashMap保存bean
    public static Map<Class<?>,Object> classToBean = new ConcurrentHashMap<>();

    //获取bean
    public static Object getBean(Class<?> cls){
   
        return classToBean.get(cls)
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值