Spring源码---BeanFactory的抽象

emmm


再菜也要读完spring。 BeanFactory是spring的核心之一,事实上context也实现了BeanFactory接口,但是context并没有真正去实现BeanFactory,而是交给了DefaultListableFactory。接着上篇,来看看context中refresh()第一步构建的BeanFactory是什么。

本系列只记录读源码的过程和自己的想法,不具备完全正确性,可能有很多自己的误解。。


DefaultListableBeanFactory类图


Selection_009


类图描述的还是比较清晰的,各个特性也也是通过继承来累加。大致上分为两部分,

略过简单的类和接口


1.AliasRegistry接口定义了如何管理别名的方法。
2.SimpleAliasRegistry则实现了AliasRegistey接口,创建了一个CurrentHashMap,用于存储别名。
3.SingletonBeanRegistry和AliasRegitry类似,但管理的是对象。

单例对象注册中心----DefaultSingletonBeanRegistry

/** Cache of singleton objects: bean name to bean instance. */
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    /** Cache of singleton factories: bean name to ObjectFactory. */
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    /** Cache of early singleton objects: bean name to bean instance. */
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    /** Set of registered singletons, containing the bean names in registration order. */
    private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

    /** Names of beans that are currently in creation. */
    private final Set<String> singletonsCurrentlyInCreation =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    /** Names of beans currently excluded from in creation checks. */
    private final Set<String> inCreationCheckExclusions =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    /** List of suppressed Exceptions, available for associating related causes. */
    @Nullable
    private Set<Exception> suppressedExceptions;

    /** Flag that indicates whether we're currently within destroySingletons. */
    private boolean singletonsCurrentlyInDestruction = false;

    /** Disposable bean instances: bean name to disposable instance. */
    private final Map<String, Object> disposableBeans = new LinkedHashMap<>();

    /** Map between containing bean names: bean name to Set of bean names that the bean contains. */
    private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);

    /** Map between dependent bean names: bean name to Set of dependent bean names. */
    private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

    /** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
    private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

以上是DefaultSingletonBeanRegistry类中的属性,基本都是final类型的Set或Map对象,存储着大量的对象,对象依赖关系等信息。从类的方法中可以看出,singletonObjects是主要的存储位置,singletonFactory是用于获取singletonObject的工厂,他们之前应该有对应关系。3个以Map结尾的属性则是定义对象之间的依存关系,containedBeanMap是包含关系,dependentBeanMap是依赖关系,dependenciesForBeanMap是被依赖关系。其中后两个是相反的,看下面代码就知道了:

public void registerDependentBean(String beanName, String dependentBeanName) {
        String canonicalName = canonicalName(beanName);
        synchronized (this.dependentBeanMap) {
            Set<String> dependentBeans =
                this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
            if (!dependentBeans.add(dependentBeanName)) {
                return;
            }
        }
        synchronized (this.dependenciesForBeanMap) {
            Set<String> dependenciesForBean =
                    this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
            dependenciesForBean.add(canonicalName);
        }
    }

同时,我们发现了一个特别的方法getSIngleton(String name, ObjectFactory factory),省略细节,方法的功能大致如下:

/**
     * Return the (raw) singleton object registered under the given name,
     * creating and registering a new one if none registered yet.
     * @param beanName the name of the bean
     * @param singletonFactory the ObjectFactory to lazily create the singleton
     * with, if necessary
     * @return the registered singleton object
     */
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
             singletonObject = singletonFactory.getObject();
             addSingleton(beanName, singletonObject);
        }
        return singletonObject;
    }

那么现在就有问题了,ObjectFactory是什么,从哪来的?暂且不去追究这些问题,但是我们知道DefaultSingletonBeanRegistry它是一个可以实例化的类,用于存储和管理Singleton(单例)对象,
并且支持ObjectFactory来获取,存储新实例。

非单例的扩展---FactoryBeanRegisterSupport


工厂里不可能只有单例模式的实例,但是单例的复用确是工厂的核心,FactoryBeanRegistrySupport添加了FactoryBean支持。

Selection_010


从上图中可以看到,FactoryBeanRegisterSupport在其父类的基础上,通过FactoryBean对象来得到指定beanName的Object对象,再看看getObjectFromFactoryBean()方法:
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
        if (factory.isSingleton() && containsSingleton(beanName)) {
            synchronized (getSingletonMutex()) {
                Object object = this.factoryBeanObjectCache.get(beanName);   // 从factory.getObject()中返回对象
                if (object == null) {
                    object = doGetObjectFromFactoryBean(factory, beanName);
                    // Only post-process and store if not put there already during getObject() call above
                    // (e.g. because of circular reference processing triggered by custom getBean calls)
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    }
                    else {
                        if (containsSingleton(beanName)) {
                            this.factoryBeanObjectCache.put(beanName, object);
                        }
                    }
                }
                return object;
            }
        }
        else {
            Object object = doGetObjectFromFactoryBean(factory, beanName);
            return object;
        }
    }

这里省略了很多的细节,但是不妨碍我们它的功能,简单点就是通过factoryBean去创建对象,如果是单例那么会先从factoryBeanOBjectCache中,如果没有会通过FactoryBean去创建并缓存到cache中;如果不是单例只创建不缓存。从这里,我们大概知道这个cache是存放的FactoryBean是单例时创建的对象,而对于FactoryBean不是单例只会创建。

休息一下


回到最初的类图中,左上角的功能基本上梳理完了,细节暂时放下。读到这里,bean对象从哪来,存到哪里大概可以猜出来。虽然我们对FactoryBean一无所知,但是我们知道可以通过它来获得一个对象,就如其注释一样。
 * Interface to be implemented by objects used within a {@link BeanFactory} which
 * are themselves factories for individual objects. If a bean implements this
 * interface, it is used as a factory for an object to expose, not directly as a
 * bean instance that will be exposed itself.

BeanFactory接口


从BeanFactory接口到configurableBeanFactoy,spring给我们定义了一个新的名称,叫做bean。在最底层的BeanFactory接口中定义的方法,其实和AliasRegisty,SingletonBeanRegister差不多,只不过BeanFactory返回的对象有一个新的叫法,叫做bean。对于BeanFactory接口和HierarchicalBeanFactory,前一个定义了基础操作,后一个则引入了Parent Bean Factory概念。主要看看ConfigurableBeanFactory接口:
/**
 * Configuration interface to be implemented by most bean factories. Provides
 * facilities to configure a bean factory, in addition to the bean factory
 * client methods in the {@link org.springframework.beans.factory.BeanFactory}
 * interface.
 *
 * <p>This bean factory interface is not meant to be used in normal application
 * code: Stick to {@link org.springframework.beans.factory.BeanFactory} or
 * {@link org.springframework.beans.factory.ListableBeanFactory} for typical
 * needs. This extended interface is just meant to allow for framework-internal
 * plug'n'play and for special access to bean factory configuration methods.

这是ConfigurableBeanFactory接口上的注释,对其接口定义的目的也很清楚(不翻译),这个接口为BeanFactory提供了可配置的选项如classLoader,ConversionService,PropertyEditorRegistrar等就不一一介绍了。

抽象bean工厂


继承自FactoryBeanRegisterSupport的AbstractFactoryBean已经彻底放弃了Registry这个命名,实现ConfigurableBeanFacory接口的它,也给我们带来了BeanFactory的抽象定义。
    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
        Object sharedInstance = getSingleton(beanName);
        Object bean;
        if (sharedInstance != null && args == null) {
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }else {
              BeanFactory parentBeanFactory = getParentBeanFactory();
              if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                   // 从父类FactoryBean中返回
                  reuturn this.parenetBeanFactory.dogetBean(....)
              }
              final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
              // 分三种情况,开始创建Bean。
              if (mbd.isSingleton()) {
                  sharedInstance = getSingleton(beanName, createBean(beanName, mbd, args))
                  bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
              }else if(mbd.isPrototype()){    // 如果有特殊属性,重新创建
                  prototypeInstance = createBean(beanName, mbd, args);
                  bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
              }else{       
                 final Scope scope = this.scopes.get(scopeName);
                 Object scopedInstance = scope.get(beanName,createBean(beanName, mbd, args));
                 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
              }
              return <T> bean;
        }

上面是AbstractFactroyBean的主要“贡献”,先看被频繁调用的getObjectFromBenInstance()方法,方法体就不贴了,贴一段注释: Get the object for the given bean instance, either the bean instance itself or its created object in case of a FactoryBean.恩,自己翻译吧。 获取bean的思路也很清晰,先从注册中心找,如果没有并且有上级(父)beanFactory,便交给上级(父)beanFactory自己不再管了。如果没有上级BeanFactory则开始创建,创建有三个分支,一是单例,二是有特殊属性,三是不包含前两个。
如果是单例: 调用父类DefaultSingletonBeanRegistry的getSIngleton()方法。这个方法第二个参数是ObjectFactory类型,getSingleton()会从ObjectFactory中获取bean,并存入singletonObjects中。
如果有特殊属性: 则直接根据其RootBeanDefinition的定义创建一个instance,注意这个instance可能就是需要返回的Bean实例,或者是FactoryBean类型。
如果前两个情况都没有: 在AbstractFactoryBean中还定义了一个scope属性,注释:/* Map from scope identifier String to corresponding Scope. /,这里还会存放额外的映射,如果这里也没有就直接跑出异常。
从上面的代码中,三个分支都调用了CreateBean方法,而这个方法是抽象的,之前的context一样的尿性,AbstractFactoryBean只定义了如何去获得一个bean,实现了BeanFactory对于bean的管理策略,继承了注册中心注册,存储。同时透过getObjectForBeanInstance()方法,我们看见在对象注册中心存放的是Bean真正的实例或者可以创建该实例的FactoryBean。而这些对象的自动创建对象过程交于其子类去实现。

尾声


Bean工厂到现在只是搭好了架子,准备好了流水线,但还没真正的产品(bean)。并没有看见完整的过程,下结论为止过找,希望错的不会太多。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值