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

Spring手撸03: 使用设计模式 实现Bean的定义/注册/获取

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

Spring手撸03: 使用设计模式 实现Bean的定义/注册/获取

撸了一遍明白为什么用封装一个ApplicationContext了, 里面很多的方法继承下来, 要去调用都一脸懵逼.

所以哦豁,又顿悟了一下为什么很多抽象类的那些实现好的方法要包保护了, 只给自己的子类去用, 外部是直接调用不到的.

就需要ApplicationContext去封装,把这些实现的方法开放出去.

先看一下整个流程之间类的关系, 这个也叫 类图

补充一下这些符号的说明

  • List item

  • -: private

  • +: public

  • ~: default

  • #: protected

  • 下划线: static

  • 斜体: 抽象类或方法(两个<<尖括号包起来也算)

冒号前有括号是方法名,反之变量名,冒号后是返回值,没有返回值可以直接连冒号一起省略

然后把这些类先创建好,简单归个类


然后上代码

BeanFactory

第一步还是BeanFactory,还是先这么简单

public interface BeanFactory {
    Object getBean(String name);
}
BeansException

专门抛Bean工厂中一些异常信息

public class BeansException extends NestedRuntimeException {

    public BeansException(String msg) {
        super(msg);
    }
}
BeanDefinition

然后上一篇我们讲过的, 是通过BeanDefinition只用来存储Bean的信息

@Data
public class BeanDefinition {

    private Class beanClass;

    //这里升级为只传类型,而不是实例 在需要的时候自己去实例
    public BeanDefinition(Class beanClass){
        this.beanClass=beanClass;
    }
}
单例注册接口定义SingletonBeanRegistry

因为上面只是传入了一个class, 所以需要一个能获取实例化对象的方法,开一个接口,让其他人去做实现

public interface SingletonBeanRegistry {

    Object getSingleton(String beanName);
}
单例注册实现DefaultSingletonBeanRegistry

这里就有了一个单例Bean的管理员

这是注册类,补充了一个注册Bean的方法.

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {

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

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

    
    protected void addSingletonBean(String beanName,Object singletonObject){
        singletonObjects.put(beanName, singletonObject);
    }
}
抽象类定义(模板方法)AbstractBeanFactory

有了个获取类的方法,就可以getBean了?

public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {

    @Override
    public Object getBean(String beanName){
        //继承自DefaultSingletonBeanRegistry 的方法
        Object bean = getSingleton(beanName);
        if (bean != null){
            return bean;
        }
        //获取不到就两个抽象方法 让实现此类的去做实现
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        return createBean(beanName,beanDefinition);

    }

    protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;

    protected abstract Object createBean(String beanName,BeanDefinition bean) throws BeansException;
}

显然还不够,因为前面说了实例化的操作还没整好呢! 所以获取不到类的时候我们就要去实例化类.

但是我不管实现,我只负责获取Bean, 我们分工明确, 我需求提在这里,其他人去帮我实现吧!

这就是模板模式, 我不止定需求,我甚至把这些需求怎么串联起来都定成了一个模板

将核心的调用逻辑在这里定义好, 后续的人不用关心怎么我的方法要怎么去串联, 尽管实现自己的功能就好.

实例化Bean类 AbstractAutowireCapableBeanFactory

这个方法负责创建Bean,另外一个BeanDefinition的事情我就不管了,所以这是一个抽象类,只实现一个抽象方法,上面遗留的另外一个需求,让子类再去实现增强.

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{

    @Override
    protected Object createBean(String name, BeanDefinition beanDefinition) throws BeansException {
        Object bean;
        try {
            bean = beanDefinition.getBeanClass().newInstance();
        }catch (InstantiationException | IllegalAccessException e) {
            throw new BeansException("In");
        }
        addSingletonBean(name,bean);
        return bean;
    }
}

前面有Bean的管理类了,但是还没有BeanDefinition的管理类

核心实现类 DefaultListableBeanFactory

然后居然是让这个叫BeanFactory的去管理,我不能理解并且大为震惊.

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry{

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

不过现在都已经好了,包括Bean的定义 注册 获取,上测试代码

@Test
public void testBeanFactory(){
    //初始化 beanFactory
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    //创建 bean信息
    BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
    String beanName = "userService";
    //注册到工厂中
    beanFactory.registerBeanDefinition(beanName,beanDefinition);
    //获取实例
    UserService userService = (UserService) beanFactory.getBean(beanName);
    userService.queryUserInfo();
    //第二次再获取应该走单例
    UserService singletonUserService = (UserService)beanFactory.getBean(beanName);

    singletonUserService.queryUserInfo();
    //是否为单例
    System.out.println(userService);
    System.out.println(singletonUserService);
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/839390.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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