2.实现Bean 对象的定义、注册和获取

183 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第18天,点击查看活动详情

通过 Spring Bean 容器创建 Bean 对象,而不是在调用时传递一个完成了实例化的Bean对象。单例对象在二次获取对象时,可以从内存中获取。

完善容器设计

在注册对象时,只注册一个类信息,而不是直接实例化,然后在获取Bean对象时再实例化,顺便加个判断当前单例对象是否缓存。

通过使用模版模式,可以统一使用核心方法的调用逻辑和标准定义。

完善容器实现

在Bean对象定义中 Object 替换成 Class。这样可以将Bean对象的实例化放到容器中处理。

Bean 对象的实例化是在初始化调用阶段由 BeanDefinition 构造函数完成。

代码实现

BeansException - 定义 Bean 异常

public class BeansException extends RuntimeException{
    public BeansException(String msg) {
        super(msg);
    }
​
    public BeansException(String msg, Throwable cause) {
        super(msg, cause);
    }
}

BeanDefinitionRegistry - Bean 定义注册接口

public interface BeanDefinitionRegistry {
​
    /**
     * @Author: Take-off
     * @Description: //TODO 向注册表中注册 BeanDefinition
     * @Date: 10:16 AM 2022/12/12
     * @Param: [beanName, beanDefinition]
     * @return: void
     **/
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
}

BeanFactory - 工厂:获取Bean

public interface BeanFactory {
    /**
     * @Author: Take-off
     * @Description: //TODO 返回Bean 的实例对象
     * @Date: 10:01 AM 2022/12/12
     * @Param: [name]
     * @return: java.lang.Object
     **/
    Object getBean(String name) throws BeansException;
}

SingletonBeanRegistry - 单例Bean 注册表

public interface SingletonBeanRegistry {
​
    /**
     * @Author: Take-off
     * @Description: //TODO 根据名字获取单例对象
     * @Date: 10:03 AM 2022/12/12
     * @Param: [beanName]
     * @return: java.lang.Object
     **/
    Object getSingleton(String beanName);
​
    /**
     * @Author: Take-off
     * @Description: //TODO 注册单例对象
     * @Date: 10:03 AM 2022/12/12
     * @Param: [beanName, singletonObject]
     * @return: void
     **/
    void registerSingleton(String beanName, Object singletonObject);
}

BeanDefinition - Bean 的定义信息

public class BeanDefinition {
    private Class beanClass;
​
    public BeanDefinition(Class beanClass) {
        this.beanClass = beanClass;
    }
​
    public Class getBeanClass() {
        return beanClass;
    }
​
    public void setBeanClass(Class beanClass) {
        this.beanClass = beanClass;
    }
}

DefaultSingletonBeanRegistry - 通用注册表实现

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
    private Map<String, Object> singletonObjects = new HashMap<>();
​
    @Override
    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }
​
    @Override
    public void registerSingleton(String beanName, Object singletonObject) {
        singletonObjects.put(beanName,singletonObject);
    }
}

DefaultSingletonBeanRegistry - 通用注册表实现

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
    private Map<String, Object> singletonObjects = new HashMap<>();
​
    @Override
    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }
​
    @Override
    public void registerSingleton(String beanName, Object singletonObject) {
        singletonObjects.put(beanName,singletonObject);
    }
}

AbstractBeanFactory - 抽象的 Bean 工厂基类,定义模板方法

public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
​
    @Override
    public Object getBean(String name) throws BeansException {
        Object bean = getSingleton(name);
        if (bean != null) {
            return bean;
        }
​
        BeanDefinition beanDefinition = getBeanDefinition(name);
        return createBean(name, beanDefinition);
    }
​
    protected abstract BeanDefinition getBeanDefinition(String beanName);
​
    protected abstract Object createBean(String beanName, BeanDefinition beanDefinition);
}

AbstractAutowireCapableBeanFactory - 实现默认bean创建的抽象bean工厂超类

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{
    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException {
        Object bean = null;
        try {
            bean = beanDefinition.getBeanClass().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new BeansException("Instantiation of bean failed", e);
        }
​
        registerSingleton(beanName, bean);
        return bean;
    }
}

DefaultListableBeanFactory - 默认的Bean工厂实现类

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry{
    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
    @Override
    protected BeanDefinition getBeanDefinition(String beanName) {
        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);
    }
}

测试类 :

public class ApiTest {
    @Test
    public void test_BeanFactory(){
        // 1.初始化 BeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
​
        // 2.注册 bean
        BeanDefinition beanDefinition = new BeanDefinition(User.class);
        beanFactory.registerBeanDefinition("user", beanDefinition);
​
        // 3.第一次获取 bean
        User userService = (User) beanFactory.getBean("user");
        userService.queryUserInfo();
​
        // 4.第二次获取 bean from Singleton
        User userService_singleton = (User) beanFactory.getBean("user");
        userService_singleton.queryUserInfo();
    }
​
}
public class User {
​
    public void queryUserInfo(){
        System.out.println("查询用户信息");
    }
}

总结

开始重点关注类之间的职责和关系。所有的接口功能设计都离不开接口、抽象类的实现和继承