手写IOC: 项目组织结构

716 阅读2分钟

Spring中的IOC设计

spring中ioc模块可以分为3中角色,分别对应3个最顶层接口:

通俗的理解:

  • BeanDefinition: 就是我们常说的Bean,理解为图书。
  • BeanDefinitionRegistry: 书架,存放书的地方。
  • BeanFactory: 图书馆,借书的地方。

在我们的实现中,同样使用了这3个概念,看下3个接口都有哪些方法:

BeanDefinition

public interface BeanDefinition {
    // 0表示未初始化
    int STATUS_UNINITIALIZED = 0;
    // 1表示已初始化
    int STATUS_INITIALIZED = 1;

    /**
     * Sets name.
     *
     * @param beanClassName the bean class name
     */
    void setName(String beanClassName);

    /**
     * Gets name.
     *
     * @return the name
     */
    String getName();

    /**
     * Sets instance.
     *
     * @param instance the instance
     */
    void setInstance(Object instance);

    /**
     * Gets instance.
     *
     * @return the instance
     */
    Object getInstance();

    /**
     * Gets bean class.
     *
     * @return bean class
     */
    Class<?> getBeanClass();

    /**
     * 判断bean是否有初始化
     *
     * @return status == {@link #STATUS_INITIALIZED} ?
     */
    Boolean isInit();

    /**
     * set status to {@link #STATUS_INITIALIZED}
     */
    void setStatusInitialized();
}

BeanDefinitionRegistry

public interface BeanDefinitionRegistry {

    /**
     * 注册一个新的Bean
     *
     * @param beanName       bean的注册使用名称
     * @param beanDefinition bean的类型
     */
    void registerBean(String beanName, BeanDefinition beanDefinition);

    /**
     * 移除一个Bean
     *
     * @param beanName 要移除的Bean的名称
     */
    void removeBean(String beanName);

    /**
     * 根据名称获取Bean
     *
     * @param beanName bean名称
     * @return 已注册的 {@link BeanDefinition} 对象
     */
    BeanDefinition getBean(String beanName);

    /**
     * 获取Bean
     * {@link BeanDefinition}
     *
     * @param beanName     bean名称
     * @param requiredType bean类型,会进行校验
     * @return 已注册的 {@link BeanDefinition} 对象
     */
    <T> BeanDefinition getBean(String beanName, Class<T> requiredType);

}

BeanFactory

public interface BeanFactory {

    /**
     * 根据名称获取bean
     *
     * @param beanName bean名称
     * @return bean名称对应的Bean
     */
    BeanDefinition getBeanInstance(String beanName);

    /**
     * 根据名称获取一个bean
     *
     * @param beanName     bean的名称
     * @param requiredType bean类型
     * @return bean名称对应的Bean
     */
    <T> T getBeanInstance(String beanName, Class<T> requiredType);
}

我们的IOC类图

对3个顶层接口都添加了默认实现类,其中比较重要的几个点:

  • BeanDefinitionRegistry 使用Map进行Bean的存储,Key为Bean的名称,Val为BeanDefinition
  • BeanDefinition中有3个字段
    private String beanName;  //bean名称
    private T beanInstance = null; // bean的实例
    private final Class<T> beanClass; //bean对应的class
    
  • BeanFactory中存储BeanDefinitionRegistry类,封装获取bean的接口,工厂对外提供