【手撸Spring】第二节:非new关键字方式实现Bean的定义、注册、获取、创建

学习地址

链接: lite-spring

欢迎点赞,关注,分享

前言

在上一节中,基于Spring容器的模型以HashMap作为容器进行对象的存储和获取。并且对象是通过new关键字创建的对象
在本节中,我们将以非new关键字进行创建对象,并且按照Spring类结构编织类之间的关系,主要分为以下步骤:
1、实现Bean的定义并且注册定义好的Bean注册到Bean定义容器
2、获取Bean分为2种情形,一是Bean在单例容器中不存在,走一遍Bean注册流程,另一个是Bean在单例容器中已存在时,直接获取
3、在Spring容器获取Bean时,将实例化Bean,以及默认当前Bean是单例的,将Bean注册到单例对象容器中

设计

Bean的定义、注册

BeanDefinition类

在BeanDefinition中使用 Class类型来接收要注册的类,后续会在实例化的时候通过反射的方式创建需要的对象

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;
    }
}

BeanDefinition容器类:

接口:BeanDefinitionRegistry
定义了如何将BeanDefinition注册到BeanDefinition容器的行为方式

单例Bean容器,用于获取单例Bean和注册单例Bean

接口:SingletonBeanRegistry

public interface SingletonBeanRegistry {

    Object getSingleton(String name);
}

容器类:DefaultSingletonBeanRegistry

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {

    private final Map<String, Object> singletonObjects = new HashMap<>();

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

    protected void addSingleton(String beanName, Object singletonObject) {
        singletonObjects.put(beanName, singletonObject);
    }
}

Bean的获取、创建

在获取Bean的过程中,会进行Bean是否已存在的判读,如果不存在,需要走创建流程并将创建好的对象放到单例对象容器池中

首先、我们需要创建工厂类的接口BeanFactory,用于对外提供工厂类的统一行为,目前主要是获取Bean的方法

public interface BeanFactory {

    Object getBean(String name) throws SpringBeansException;
}

其次、创建实现了工厂类接口的抽象类AbstractBeanFactory,是获取Bean的具体实现类,但在获取Bean的过程中,Bean如果没有创建,需要获取Bean的定义,并且创建Bean

public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {

    @Override
    public Object getBean(String beanName) {
        Object bean = getSingleton(beanName);
        if (bean != null) {
            System.out.println("无需创建,从缓存获取");
            return bean;
        }
        BeanDefinition definition = getBeanDefinition(beanName);
        return createBean(beanName, definition);
    }

    protected abstract BeanDefinition getBeanDefinition(String beanName) throws SpringBeansException;

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

然后、为了实现职责分工以及对于创建Bean可以支持多实现,实现一个创建Bean的抽象类AbstractAutowireCapableBeanFactory,使用反射的方式创建Bean

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {

    @Override protected Object createBean(String beanName, BeanDefinition beanDefinition) throws SpringBeansException {
        Object bean;
        try {
            bean = beanDefinition.getBeanClass().newInstance();
        } catch (Exception e) {
            throw new SpringBeansException("Instantiation of bean failed", e);
        }
        addSingleton(beanName, bean);
        return bean;
    }
}

最后、定义一个实现类用于实现抽象工厂类和BeanDefinition容器类的最终实现类DefaultListableBeanFactory,以及对外提供BeanDefinition注册的行为和获取行为

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {

    private final Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();

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

    @Override protected BeanDefinition getBeanDefinition(String beanName) throws SpringBeansException {
        BeanDefinition definition = beanDefinitionMap.get(beanName);
        if (definition == null)
            throw new SpringBeansException("No Bean Named '" + beanName + "' is defined");
        return definition;
    }
}

示例、单元测试

定义一个Bean

public class UserService {

    public void getUser() {
        System.out.println("获取用户对象");
    }
}

测试Bean的定义、注册、获取、创建

@Test
    public void test_bean_factory() {
        //1.初始化Bean工厂
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //2.注册Bean
        BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
        beanFactory.registerBeanDefinition("userService", beanDefinition);
        //3.第一次获取Bean
        UserService userService = (UserService) beanFactory.getBean("userService");
        userService.getUser();
        //4.第二次获取Bean,且是Singleton类型
        UserService userService_singleton = (UserService) beanFactory.getBean("userService");
        userService_singleton.getUser();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值