栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

手写spring02- 实现bean的定义 注册 获取

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

手写spring02- 实现bean的定义 注册 获取

文章目录
      • 目标
      • 设计
      • 实现
        • BeanDefinition 的定义
        • 单例注册接口的定义与实现
      • 定义bean工厂 BeanFactory
        • 抽象类定义模板方法 AbstractBeanFactory
      • 实例化Bean类 AbstractAutowireCapableBeanFactory
      • 核心类实现(DefaultListableBeanFactory)
      • 测试

目标

此文中实现了spring容器的粗略的版本
https://javaweixin6.blog.csdn.net/article/details/124256888

此节要实现bean容器关于对象的注册和获取 .
Bean的创建交给容器, 而不是在调用的时候, 传递一个实例化好的bean对象.
并且对对象进行单例模式的处理. 完善类的结构, 使其容易扩展.

设计

在spring的bean注册的时候, 只注册一个类的信息, 而不会直接把实例化的信息注册到spring容器中去.则BeanDefinition 的属性为Class.

在获取bean对象的时候, 处理bean对象的实例化操作, 以及判断当前单例对象在容器中是否已经缓存起来了.

  • 定义BeanFactory 这样的工厂, 提供Bean的获取方法, 这个Bean工厂接口由抽象类AbstractBeanFactory实现, 这个抽象类定义了模板方法模式的写法, 定义了标准, 控制了后续的实现者不用关心调用逻辑, 按照统一的方式执行即可, 类的继承者, 只需要关心具体方法的逻辑实现.
实现

实现的uml图如下

BeanDefinition 的定义

属性为Class

public class BeanDefinition {

    private Class beanClass;

    // bean的实例化,是在BeanDefinition 的构造函数
    public BeanDefinition(Class beanClass) {
        this.beanClass = beanClass;
    }

    public Class getBeanClass() {
        return beanClass;
    }

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

bean的实例化操作是放在初始化调用阶段传递给BeanDefinition的构造函数的.

单例注册接口的定义与实现

SingletonBeanRegistry

public interface SingletonBeanRegistry {

    Object getSingleton(String beanName);
}

单例的实现类DefaultSingletonBeanRegistry

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
    // 单例对象的缓存
    private final Map singletonObjects = new HashMap<>();

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

    
    protected void addSingleton(String beanName, Object singletonObject) {
        singletonObjects.put(beanName, singletonObject);
    }
}
定义bean工厂 BeanFactory
public interface BeanFactory {

    Object getBean(String name) throws BeansException;

}
抽象类定义模板方法 AbstractBeanFactory
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {

    @Override
    public Object getBean(String name) throws BeansException {
        Object bean = super.getSingleton(name);
        if (bean != null) {
            // 从单例池中获取的不为null  则直接返回
            return bean;
        }
        // 单例池中没有, 则创建bean 先获取bean 的定义信息
        BeanDefinition beanDefinition = getBeanDefinition(name);
        // 创建bean
        return createBean(name, beanDefinition);
    }

    protected abstract Object createBean(String name, BeanDefinition beanDefinition) throws BeansException;

    // 模板方法 获取bean 的定义信息
    protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;
}

对于接口BeanFactory的实现, 做的处理是先从单例池中获取, 如果获取不到, 则去获取bean的定义信息, 并去创建bean. 但获取bean的信息和创建bean ,定义了抽象方法, 由其子类实现.

实例化Bean类 AbstractAutowireCapableBeanFactory
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {

    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException {
        Object bean;
        try {
            // 获取bean 的class 反射去创建对象 此处的不足是只能构建无参构造的对象
            bean = beanDefinition.getBeanClass().newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BeansException("Instantiation of bean failed", e);
        }
        addSingleton(beanName, bean);
        return bean;
    }
}

对于无参构造, 实例化了bean对象. 后续会优化有参构造.

核心类实现(DefaultListableBeanFactory)
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {

    private final Map 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);
    }
}
测试

测试用的业务类

public class UserService {
    public void queryUserInfo() {
        System.out.println("查询用户信息");
    }
}

测试类

public class ApiTest {
    @Test
    public void test_BeanFactory() {
        // 1. 初始化BeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        //2 . 注入bean   Bean 的实例化操作是放在初始化调用阶段传递给 BeanDefinition 构造函数的。
        BeanDefinition beanDefinition = new BeanDefinition( UserService.class);
        beanFactory.registerBeanDefinition("userService", beanDefinition);

        //3 . 第一次获取bean
        UserService userService = (UserService) beanFactory.getBean("userService");
        userService.queryUserInfo();

        // 第二次获取bean
        userService = (UserService) beanFactory.getBean("userService");
        userService.queryUserInfo();
    }
}

打印如下

查询用户信息
查询用户信息

重要的代码的设计思想 而不要成为码农

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/831222.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号