手写简易版Spring IOC容器05【学习】

拓展bean的作用域以及实现FactoryBean.
在之前实现的bean中获取bean默认都是单例的也就是只创建一个bean对象,这次拓展beanDefinition添加单例实现和prototype实现

bean作用域

beanDefinition添加字段

String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

private boolean singleton = true;

private boolean prototype = false;

public void setScope(String scope){
   this.scope = scope;
   this.singleton = SCOPE_SINGLETON.equals(scope);
   this.prototype = SCOPE_PROTOTYPE.equals(scope);
}

registry bean时添加bean的scope

// 如果配置了scope设置scope..
if(StrUtil.isNotEmpty(beanScope)){
	beanDefinition.setScope(beanScope);
}

创建bean时进行判断

@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
    Object bean = null;
    try {
        bean = createBeanInstance(beanDefinition, beanName, args);
        // 给 Bean 填充属性
        applyPropertyValues(beanName, bean, beanDefinition);
        // 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法
        bean = initializeBean(beanName, bean, beanDefinition);
    } catch (Exception e) {
        throw new BeansException("Instantiation of bean failed", e);
    }

    // 注册实现了 DisposableBean 接口的 Bean 对象
    registerDisposableBeanIfNecessary(beanName, bean, beanDefinition);
    
    // 判断 SCOPE_SINGLETON、SCOPE_PROTOTYPE
    if(beanDefinition.isSingleton()){
        addSingleton(beanName, bean);
    }
    // 如果不是单例则直接创建对象返回
    return bean;
}

扩展FactoryBean

factoryBean本质也是一个bean对象,区别于普通的bean,它生成bean。

FactoryBean接口

public interface FactoryBean<T> {

    T getObject() throws Exception;

    Class<?> getObjectType();

    boolean isSingleton();

}

FactoryBeanRegistrySupport FactoryBean注册

存放的都是通过FactoryBean 创建的对象

public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry{

    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>();

    // 从缓存中获取
    protected Object getCachedObjectForFactoryBean(String beanName){
        Object object = this.factoryBeanObjectCache.get(beanName);
        return (object != NULL_OBJECT ? object : null);
    }

    // 从FactoryBean中获取.
    protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) {
        // 判断当前factory是单例吗
        if (factory.isSingleton()) {
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
                object = doGetObjectFromFactoryBean(factory, beanName);
                this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
            }
            return (object != NULL_OBJECT ? object : null);
        }else{
            return doGetObjectFromFactoryBean(factory, beanName);
        }
    }

    private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName){
        try {
            return factory.getObject();
        }catch (Exception e){
            throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
        }
    }
    
}

AbstractBeanFactory.GetBean方法

getBean时首先拿到当前bean对象判断是FactoryBean对象吗?如果是需要从上一步中FactoryBeanRegistry的map中来获取对象。 如果不是先创建FactoryBean对象还是继续去FactoryBean中去获取。

protected <T> T doGetBean(final String name, final Object[] args) {
    Object sharedInstance = getSingleton(name);
    if (sharedInstance != null) {
        // 如果是 FactoryBean,则需要调用 FactoryBean#getObject
        return (T) getObjectForBeanInstance(sharedInstance, name);
    }
    BeanDefinition beanDefinition = getBeanDefinition(name);
    Object bean = createBean(name, beanDefinition, args);
    return (T) getObjectForBeanInstance(bean, name);
}

getObjectForBeanInstance

如果拿到的不是FactoryBean类型的对象则直接返回

private Object getObjectForBeanInstance(Object beanInstance, String beanName) {
    // 如果当前拿的对象不是FactoryBean 返回单例中存放的bean对象
    if (!(beanInstance instanceof FactoryBean)) {
        return beanInstance;
    }
    // 否则去factoryBean的缓存中去拿对象.
    Object object = getCachedObjectForFactoryBean(beanName);
    // 缓存中没有则通过FactoryBean去创建这个对象
    if(object == null){
        FactoryBean<?> factoryBean = (FactoryBean<?>) beanInstance;
        object = getObjectFromFactoryBean(factoryBean,beanName);
    }
    return object;
}

getObjectFromFactoryBean

protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) {
    // 判断当前factory是单例吗
    if (factory.isSingleton()) {
        Object object = this.factoryBeanObjectCache.get(beanName);
        if (object == null) {
            object = doGetObjectFromFactoryBean(factory, beanName);
            this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
        }
        return (object != NULL_OBJECT ? object : null);
    }else{
        return doGetObjectFromFactoryBean(factory, beanName);
    }
}

相关推荐

  1. 简易Spring IOC容器05学习

    2024-07-23 05:42:02       20 阅读
  2. 简易Spring IOC容器02学习

    2024-07-23 05:42:02       15 阅读
  3. 简易Spring IOC容器04学习

    2024-07-23 05:42:02       22 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-23 05:42:02       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-23 05:42:02       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-23 05:42:02       61 阅读
  4. Python语言-面向对象

    2024-07-23 05:42:02       71 阅读

热门阅读

  1. 速盾:cdn技术实现原理是什么?

    2024-07-23 05:42:02       21 阅读
  2. Windows通过命令查看mac : getmac

    2024-07-23 05:42:02       20 阅读
  3. CentOS搭建 Mono 开发环境

    2024-07-23 05:42:02       19 阅读
  4. MVC(Model-View-Controller)架构简介

    2024-07-23 05:42:02       20 阅读
  5. 科普文:重读并翻译分布式计算经典文论-MapReduce

    2024-07-23 05:42:02       16 阅读
  6. Apache Commons技术详解

    2024-07-23 05:42:02       21 阅读
  7. mqtt.fx 下载 安装 配置

    2024-07-23 05:42:02       20 阅读
  8. 保护Mojo模型:确保数据模型安全的策略

    2024-07-23 05:42:02       21 阅读
  9. 设计模式-适配器模式

    2024-07-23 05:42:02       19 阅读
  10. C语言——字符串中sizeof和strlen的辨析

    2024-07-23 05:42:02       21 阅读