(造轮子)手写Spring框架-BeanDefinition and BeanDefinitionRegisty

126 阅读1分钟

手写Spring框架-BeanDefinition and BeanDefinitionRegisty

建议订阅博主专栏,从下到上系统手写spring源码,体会其中过程!

  1. 定义BeanDefinition对象,由于我们做的是简易的spring框架,只需要记录bean的Class信息,代码如下:
/**
 * BeanDefinition实例保存bean的信息,包括class类型、方法构造参数、是否为单例等,此处简化只包含class类型
 * @author WangChao
 * @version 1.0
 * @date 2023/6/14 12:07
 */
public class BeanDefinition {
    private Class beanClass;

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4eb0e00c195947cd90392540c6d83bc0~tplv-k3u1fbpfcp-watermark.image?)
    public BeanDefinition(Class beanClass){
        this.beanClass = beanClass;
    }

![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/408a8746495141d6b7069d50434fb779~tplv-k3u1fbpfcp-watermark.image?)
    public Class getBeanClass(){
        return beanClass;
    }

    public void setBeanClass(Class beanClass){
        this.beanClass = beanClass;
    }
}
  1. 定义单例注册表接口,用于和DefaultSingletonBeanRegistry分离开,定义获取单例bean的方法,spring默认采用的单例模式注册bean对象
/**
 * 单例注册表
 * @author WangChao
 * @version 1.0
 * @date 2023/6/14 12:09
 */
public interface SingletonBeanRegistry {
    Object getSingleton(String beanName);
}
  1. 编写单例bean注册实现类,用一个HashMap记录beanName和Object对象注册关系,为后边的AbstractBeanFactory中getBean服务
/**
 * 单例bean注册实现类
 * @author WangChao
 * @version 1.0
 * @date 2023/6/14 12:15
 */
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
    private Map<String, Object> singletonObjects = new HashMap<>();

    @Override
    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }

    protected void addSingleton(String beanName,Object singletonObject){
        singletonObjects.put(beanName,singletonObject);
    }
}
  1. 编写AbstractBeanFactory,这是一个顶层抽象方法,里面有获取bean的初步实现,如果在单例HashMap中能拿到对象,则获取该bean对象,然后返回,拿不到,则调用抽象方法createBean方法
/**
 * 抽象创建bean的工厂
 * @author WangChao
 * @version 1.0
 * @date 2023/6/14 12:13
 */
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {

    @Override
    public Object getBean(String beanName) throws BeansException {
        Object bean = getSingleton(beanName);
        if(bean != null){
            return bean;
        }
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        return createBean(beanName,beanDefinition);
    }

    /**
     * 创建一个bean
     * @param beanName bean名称
     * @param beanDefinition
     * @return
     * @throws BeansException
     */
    protected abstract Object createBean(String beanName,BeanDefinition beanDefinition) throws BeansException;

    /**
     * 根据bean名称获取BeanDefinition
     * @param beanName
     * @return
     * @throws BeansException
     */
    protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
}

其中实现的BeanFactory是一个获得bean的工厂,实现其接口,重载getBean方法

/**
 * bean容器
 * @author WangChao
 * @version 1.0
 * @date 2023/6/14 11:15
 */
public interface BeanFactory {
    /**
     * 获取bean
     * @param beanName
     * @return
     */
    Object getBean(String beanName);
}
  1. 编写AbstractAutowireCapableBeanFactory类,这个类继承了上面写的AbstractBeanFactory,重写了里面的createBean方法,该方法调用了doCreateBean方法,在doCreateBean方法中根据beanName和在HashMap拿到的beanDefinition通过反射拿到Class对象,后new一个Class实例对象,再将该对象放到单例HashMap中,key是beanName,代码如下:
/**
 * @author WangChao
 * @version 1.0
 * @date 2023/6/14 12:35
 */
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{

    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException{
        return doCreateBean(beanName,beanDefinition);
    }

    /**
     * 创建bean示例
     * @param beanName
     * @param beanDefinition
     * @return
     * @throws BeansException
     */
    protected Object doCreateBean(String beanName,BeanDefinition beanDefinition) throws BeansException{
        Class beanClass = beanDefinition.getBeanClass();
        Object bean;
        try{
            bean = beanClass.newInstance();
        } catch (Exception e) {
            throw new BeansException("Instantiation of bean failed", e);
        }
        addSingleton(beanName,bean);
        return bean;
    }
  1. 编写DefaultListableBeanFactory,该类继承了AbstractBeanFactory、AbstractAutowireCapableBeanFactory,实现了BeanDefinitionRegistry拥有getBean、setBean、registerBeanDefinition、getBeanDefinition等方法同时 AbstractBeanFactory又继承了单例bean的get方法,可以获取单例bean,总的来说,这个类可以提供更多的方法,集成了以上说的类,并重写了getBeanDefinition、registerBeanDefinition这两个方法,也是用一个HashMap代码如下:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry{
    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();

    @Override
    protected BeanDefinition getBeanDefinition(String beanName) throws BeansException {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) {
            throw new BeansException("No bean named '" + beanName + "' is defined");
        }
        return beanDefinition;
    }

    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName,beanDefinition);
    }
}

该类拥有的方法如下图:

image.png

总结

通过手写该BeanDefinition的注册和获取过程,了解到了bean在容器中封装和获取,本质是HashMap和单例的应用,同时用到了经典的设计模式,使得代码更加的优雅,其中接口和集成的使用更是秒不可言,一层层实现了最终的目标!