当前位置:   article > 正文

第二步->手撕spring源码之bean操作

第二步->手撕spring源码之bean操作

本步骤目标
本步骤继续完善 Spring Bean 容器框架的功能开发,在这个开发过程中会用到较多的接口、类、抽象类,它们之间会有类的实现、类的继承。
这一次我们把 Bean 的创建交给容器,而不是我们在调用时候传递一个实例化好的 Bean 对象,另外还需要考虑单例对象,在对象的二次获取时是可以从内存中获取对象的。此外不仅要实现功能还需要完善基础容器框架的类结构体。
设计如下操作

A:这里主要使用魔板方法模式进行设计定义 BeanFactory 这样一个 Bean 工厂,提供 Bean 的获取方法 getBean(String name),之后这个 Bean 工厂接口由抽象类 AbstractBeanFactory 实现
B:那么在继承抽象类 AbstractBeanFactory 后的 AbstractAutowireCapableBeanFactory 就可以实现相应的抽象方法了,因为 AbstractAutowireCapableBeanFactory 本身也是一个抽象类,
C:单例 SingletonBeanRegistry 的接口定义实现,而 DefaultSingletonBeanRegistry 对接口实现后,会被抽象类 AbstractBeanFactory 继承。
spring的bean的全景图
在这里插入图片描述

以下为实战部分

public class BeanDefinition {
    private Class classBean;
    public BeanDefinition(Class classBean){
        this.classBean=classBean;
    }

    public Class getClassBean() {
        return classBean;
    }

    public void setClassBean(Class classBean) {
        this.classBean = classBean;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在 Bean 定义类中已经把上一步骤中的 Object bean 替换为 Class,这样就可以把 Bean 的实例化操作放到容器中处理了。

public interface SingletonBeanRegistry {
    Object getSingleton(String beanName);
}

  • 1
  • 2
  • 3
  • 4

这里接口之定义一个获取bean的方法。

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {

    Map<String, Object> singletonObjects = new ConcurrentHashMap<>();

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

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

以上的DefaultSingletonBeanRegistry 是默认注册bean的抽象实现,实现了一个受保护的 addSingleton 方法,这个方法可以被继承此类的其他类调用。

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

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

    protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

1:AbstractBeanFactory 首先继承了 DefaultSingletonBeanRegistry,也就具备了使用单例注册类方法。
2:BeanFactory 的实现,在方法 getBean 的实现过程中可以看到,主要是对单例 Bean 对象的获取以及在获取不到时需要拿到 Bean 的定义做相应 Bean 实例化操作。那么 getBean 并没有自身的去实现这些方法,而是只定义了调用过程以及提供了抽象方法,由实现此抽象类的其他类做相应实现。
3:后续继承抽象类 AbstractBeanFactory 的类有两个,包括:AbstractAutowireCapableBeanFactory、DefaultListableBeanFactory,这两个类分别做了相应的实现处理。
实例化Bean类(AbstractAutowireCapableBeanFactory)

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

核心类实现(DefaultListableBeanFactory)


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

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

    @Override
    protected BeanDefinition getBeanDefinition(String name) throws BeansException {
        BeanDefinition beanDefinition = beanDefinitionMap.get(name);
        if (beanDefinition == null) throw new BeansException("No bean named '" + name + "' is defined");
        return beanDefinition;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

1:DefaultListableBeanFactory 在 Spring 源码中也是一个非常核心的类,在我们目前的实现中也是逐步贴近于源码,与源码类名保持一致。
2:DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory 类,也就具备了接口 BeanFactory 和 AbstractBeanFactory 等一连串的功能实现。所以有时候你会看到一些类的强转,调用某些方法,也是因为你强转的类实现接口或继承了某些类。
3:除此之外这个类还实现了接口 BeanDefinitionRegistry 中的 registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 方法,当然你还会看到一个 getBeanDefinition 的实现,这个方法我们文中提到过它是抽象类 AbstractBeanFactory 中定义的抽象方法。现在注册Bean定义与获取Bean定义就可以同时使用了,是不感觉这个套路还蛮深的。接口定义了注册,抽象类定义了获取,都集中在 DefaultListableBeanFactory 中的 beanDefinitionMap 里
以下进行测试

@Test
    public void Test_BeanFAcotyr() {
        // 1.初始化 BeanFactory
        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.queryUserInfo();
    }

    @Test
    public void Test_BeanFAcotyr_two() {
        // 1.初始化 BeanFactory
        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.queryUserInfo();
//
        // 4.第二次获取 bean from Singleton
        UserService userService_singleton = (UserService) beanFactory.getBean("userService");
        userService_singleton.queryUserInfo();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
查询用户信息
查询用户信息

Process finished with exit code 0

  • 1
  • 2
  • 3
  • 4
  • 5

总结
这里与上一步的操作区别在于 这里把 UserService.class 传递给了 BeanDefinition 而不是像上一章节那样直接 new UserService() 操作。
这里会有两次测试信息,一次是获取 Bean 时直接创建的对象,另外一次是从缓存中获取的实例化对象。
在这里插入图片描述
以上是第二步->手撕spring源码之bean操作 关注老哥带你上高速哦。。。。 后续继续完成手写spring源码。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/588285
推荐阅读
相关标签
  

闽ICP备14008679号