emmm
再菜也要读完spring。 BeanFactory是spring的核心之一,事实上context也实现了BeanFactory接口,但是context并没有真正去实现BeanFactory,而是交给了DefaultListableFactory。接着上篇,来看看context中refresh()第一步构建的BeanFactory是什么。
本系列只记录读源码的过程和自己的想法,不具备完全正确性,可能有很多自己的误解。。
DefaultListableBeanFactory类图
类图描述的还是比较清晰的,各个特性也也是通过继承来累加。大致上分为两部分,
略过简单的类和接口
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支持。
从上图中可以看到,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)。并没有看见完整的过程,下结论为止过找,希望错的不会太多。