Spring是如何通过BeanDefinition定义Bean

一,单例 Bean 注册的局限性

在前面的介绍中说道了通过 SingletonBeanRegistry 实现 getBean,但是效果比较单一只能从单例池中获取,如果单例池当中不存在就没法实现了。

所以在这里又引入 BeanDefinition,通过 Bean 的定义信息实现 Bean 的创建逻辑

创建一个简单的 BeanDefinition

public class BeanDefinition {  
    // Bean名称  
    private String beanName;  
    // Bean的Class对象  
    private Class beanClass;  

    public BeanDefinition(Class beanClass){  
        this(beanClass,null );  
    }  

    public Class getBeanClass() {  
        return beanClass;  
    }  

    public void setBeanClass(Class beanClass) {  
        this.beanClass = beanClass;  
    }  

    public String getBeanName() {  
        return beanName;  
    }  

    public void setBeanName(String beanName) {  
        this.beanName = beanName;  
    }  
}

二,扩展AbstractBeanFactory实现完整获取逻辑

之后我们就可以对 AbstractBeanFactory 进行扩展,在单例池当中不存在的时候创建 Bean,那么由于创建 Bean 的逻辑需要获取到 BeanDefinition,那么 AbstractBeanFactory 就应该有 getBeanDefinition 的方法来获取到 BeanDefinition。

@Override  
public Object getBean(String beanName) {  
    // 尝试从缓存当中获取Bean  
    Object bean = super.getSingletonBean(beanName);  
    if (bean != null){  
        return bean;  
    }  

    // 如果没有尝试创建Bean,Bean的创建需要通过BeanDefinition  
    BeanDefinition beanDefinition = getBeanDefinition(beanName);  

    // 创建Bean  
    return createBean(beanName , beanDefinition);  
}  

protected abstract Object createBean(String beanName, BeanDefinition beanDefinition);  
protected abstract BeanDefinition getBeanDefinition(String beanName);

那么除此之外对于每一个 Bean 都需要拥有自己的 BeanDefinition,也就是说我们还需要一个类,类似于刚才的 AbstractSingletonBeanRegister,在其中定义保存不同类的 beanDefinition 的数据结构,并提供 get/set 方法。

public interface BeanDefinitionRegister {  
    /**  
     * 注册Bean  
     * @param beanName  
     * @param beanDefinition     
     */    
    void registerBeanDefinition(String beanName , BeanDefinition beanDefinition);  
}

通过 DefaultListableBeanFactory 实现 BeanDefinitionRegister

public class DefaultListableBeanFactory implements BeanDefinitionRegister {  
    private Map<String , BeanDefinition> beanDefinitionMap = new HashMap<>();  

    /**  
     * 注册BeanDefinition  
     * @param beanName  
     * @param beanDefinition  
     */    
    @Override  
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {  
        beanDefinitionMap.put(beanName,beanDefinition);  
    }  

    /**  
     * 获取BeanDefinition  
     * @param beanName  
     * @return  
     */    
    @Override  
    protected BeanDefinition getBeanDefinition(String beanName) {  
        return beanDefinitionMap.get(beanName);  
    }  
}

三,整体设计思路梳理

好了,现在我们再来捋一下思路,我们有了 SingletonBeanRegister 与其默认实现 DefaultSingletonBeanRegistry。通过单列池我们就可以获取加入到缓存当中的 Bean,但是在获取 bean 的过程当中如果 Bean 不存在于单列池当中,我们就需要去创建 Bean,再讲创建好的 Bean 放入到单列池当中。除此之外在创建 Bean 的过程当中又会涉及到 BeanDefinition,通过 BeanDefinition 当中的 Class 属性反射创建对象,所以我们又创建了 BeanDefinition 与 DefaultSingletonBeanRegistry。

那么流程讲完了我们重新回到 AbstractBeanFactory 补充创建 Bean 与获取 BeanDefinition 的逻辑

在这里我们由于获取 BeanDefinition 在单一的 AbstractBeanFactory 是无法实现的所以包含创建 Bean 的方法在内我们都委托子类来实现

public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {  
    /**  
     * 获取Bean  
     * 包含创建Bean的流程,在创建Bean的流程当中会先从缓存当中取,如果没有则创建  
     * 在获取Bean之前需要获取到Bean的定义信息也就是BeanDefinition  
     * 1,从缓存当中获取Bean  
     * 2,尝试创建Bean并返回  
     *  
     * @param beanName Bean名称  
     */  
    @Override  
    public Object getBean(String beanName) {  
        // 尝试从缓存当中获取Bean  
        Object bean = super.getSingletonBean(beanName);  
        if (bean != null){  
            return bean;  
        }  

        // 如果没有尝试创建Bean,Bean的创建需要通过BeanDefinition  
        BeanDefinition beanDefinition = getBeanDefinition(beanName);  

        // 创建Bean  
        return createBean(beanName , beanDefinition);  
    }  

    protected abstract Object createBean(String beanName, BeanDefinition beanDefinition);  
    protected abstract BeanDefinition getBeanDefinition(String beanName);  
}

AbstractAutowireCapableBeanFactory 实现 createBean 方法

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {  
    private InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy();  

    /**  
     * @param beanName Bean名称  
     * @param beanDefinition Bean的定义信息  
     * @return Bean实列  
     */  
    @Override  
    protected Object createBean(String beanName, BeanDefinition beanDefinition) {  
        return doCreateBean(beanName , beanDefinition);  
    }  

    /**  
     * 执行具体创建Bean的逻辑  
     *  
     * 如何创建Bean?  
     * 通过beanDefinition当中保存的Bean的Class对象,通过反射的方式创建Bean  
     */    
    private Object doCreateBean(String beanName, BeanDefinition beanDefinition) throws BeanException {  
        // 通过反射创建对象  
        Object bean = null;  
        try {  
            // 通过InstantiationStrategy实例化Bean  
            bean = createBeanInstance(beanDefinition);  
        } catch (Exception e) {  
            throw new BeanException(e.getMessage());  
        }  

        // 创建完毕后加入缓存  
        super.addSingletonBean(beanName, bean);  

        return bean;  
    }  

    /**  
     * 创建并返回一个Bean实例  
     * 此方法根据Bean定义来实例化Bean,具体实例化策略由获取到的实例化策略决定  
     *  
     * @param beanDefinition Bean的定义,包含了创建Bean实例所需的信息  
     * @return 实例化的Bean对象  
     */  
    private Object createBeanInstance(BeanDefinition beanDefinition) { 
        // 获取BeanDefinition中定义的类  
        Class aClass = beanDefinition.getBeanClass();  
        try {  
            // 获取无参构造  
            Constructor declaredConstructor = aClass.getDeclaredConstructor();  
            // 使用无参构造实例化对象并返回  
            return declaredConstructor.newInstance();  
        } catch (Exception e) {  
            // 如果实例化过程中发生异常,抛出BeanException  
            throw new BeanException(e.getMessage());  
        } 
    }  
}

四,最终容器类设计

这里我们来想一下,getBeanDefinition 这个方法是在 DefaultListableBeanFactory 当中实现的,但是我们的 AbstractAutowireCapableBeanFactory 需要用到这个方法,而且在它的父类 AbstractBeanFactory 当中其实也定义了该抽象方法,在这里我们其实也可以让 AbstractAutowireCapableBeanFactory 实现 BeanDefinitionRegistry 然后与 DefaultListableBeanFactory 一样实现相关的方法与逻辑,但是这样做的话会导致太臃肿了。所以在这里我们可以让 DefaultListableBeanFactory 继承 AbstractAutowireCapableBeanFactory,这样他就包含了创建 Bean 的功能,同时也实现了 BeanDefinition 的注册与获取

我们再看一下继承关系

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegister {  
}

从这张图就可以看出所有的继承关系了,我们也可以发现 DefaultListableBeanFactory 同时包含了 SingletonBeanRegister 与 BeanDefinitionRegistry 的所有功能,也是容器的核心类

![[Pasted image 20250414175939.png]]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

攒了一袋星辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值