spring-beans包源码阅读-4-BeanFactory

前置

Spring阅读前言-里面讲了一些心路历程

spring-beans包源码阅读-2-BeanWrapper

spring-beans包源码阅读-3-BeanDefinition

终于到重点啦!由于BeanFactory太复杂了,这次我们会用单元测试调试跟踪源码。

一. BeanFactory和FactoryBean

先聊一聊BeanFactory和FactoryBean,期初我看源码的时候,看到这两个接口真是异常懵逼,他们的方法还很相似,都是获取一个Object。其实这两个接口八竿子打不着,九杆子能打着一点,这里就先讲一讲这两个接口各是干什么的。

1. BeanFactory

spring的总工厂,所有的bean的实例都保存在这个工厂中,并提供了各种不同的方法去获取各种的bean的实例。这个接口没啥好多说的,最核心的接口,等下我们会重点分析这个接口。

2. FactoryBean

从名字来看,首先这是一个Bean,然后这是一个工厂,其部分注释如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
* 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.
*
* <p><b>NB: A bean that implements this interface cannot be used as a normal bean.</b>
* A FactoryBean is defined in a bean style, but the object exposed for bean
* references ({@link #getObject()}) is always the object that it creates.

public interface FactoryBean<T> {

@Nullable
T getObject() throws Exception;

...
}

FactoryBean才是真正的我们熟悉的”工厂方法模式”,其实命名为Factory会更好,但是在spring中,所有的实体都是Bean,一个Factory也不例外是一个Bean,所以就命名为了FactoryBean。实现了这个接口的类就是一个工厂类,里面需要实现获取具体对象的逻辑。

3. FactoryBean,工厂方法模式

这里不会详细介绍什么是工厂模式,因为在进行spring源码阅读的时候会假定已经掌握了各种常用的设计模式。

那么FactoryBean是怎么使用工厂方法模式的呢?

FactoryBean有一个直接实现类:AbstractFactoryBean,里面实现了T getObject() throws Exception方法:

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
/**
* Expose the singleton instance or create a new prototype instance.
* @see #createInstance()
* @see #getEarlySingletonInterfaces()
*/
@Override
public final T getObject() throws Exception {
if (isSingleton()) {
return (this.initialized ? this.singletonInstance : getEarlySingletonInstance());
}
else {
return createInstance();
}
}

/**
* Template method that subclasses must override to construct
* the object returned by this factory.
* <p>Invoked on initialization of this FactoryBean in case of
* a singleton; else, on each {@link #getObject()} call.
* @return the object returned by this factory
* @throws Exception if an exception occurred during object creation
* @see #getObject()
*/
protected abstract T createInstance() throws Exception;

最后扔给了一个模板方法createInstance()去完成具体的实例的创建工作,这就是一个标准的工厂模式。

二. How getBean() works.

BeanFactory接口的集大成者就是DefaultListableBeanFactory,整个Bean的实例化过程、实例化策略等等内容,都在DefaultListableBeanFactory以及其父类AbstractAutowireCapableBeanFactory和AbstractBeanFactory中,故也是我们研究的重点对象。

这个继承关系也是没谁了。。

1. AliasRegistry & SimpleAliasRegistry

bean可能有各种别名,这个接口用来提供给一个Bean添加一些别名,并提供根据某个别名查找一个Bean的逻辑。所有的别名引用关系保存在一个map中,取的时候是递归算法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// SimpleAliasRegistry.java
/**
* Transitively retrieve all aliases for the given name.
* @param name the target name to find aliases for
* @param result the resulting aliases list
*/
private void retrieveAliases(String name, List<String> result) {
this.aliasMap.forEach((alias, registeredName) -> {
if (registeredName.equals(name)) {
result.add(alias);
retrieveAliases(alias, result);
}
});
}

2. DefaultSingletonBeanRegistry

提供了保存单例Bean的Map、Set等集合,不仅仅是完全体的Bean,也有正在创建中的Bean,以及Bean之间的依赖关系都在这里。看看这个类的属性,就知道它的功能:

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
28
29
30
31
32
33
34
35
36
37
38
/** 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);

3. FactoryBeanRegistrySupport

这个类提供了对FactoryBean的支持,有一些bean不是直接创建的,而是通过FactoryBean工厂创建的,我们在上文讲过了FactoryBean。这个类的主要功能就是从FactoryBean中调用getObject方法拿到工厂创建出来的实例。

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
/**
* Obtain an object to expose from the given FactoryBean.
* @param factory the FactoryBean instance
* @param beanName the name of the bean
* @return the object obtained from the FactoryBean
* @throws BeanCreationException if FactoryBean object creation failed
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {

Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 就是这句,调用了FactoryBean的getObject()方法,拿到工厂创建的实例。
object = factory.getObject();
}
}

很简单的一个类,不多讲了,这个类的代码也很简单,主要做了各种异常控制、权限检查、log打印,真正的关键代码只有object = factory.getObject();这一行。

4. AbstractBeanFactory & AbstractAutowireCapableBeanFactory

里面实现了BeanFactory中的核心方法:getBean

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}

/**
* Return an instance, which may be shared or independent, of the specified bean.
*/
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

...

final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
...
}

前面如果设置了ParentBeanFactory,那么调用ParentBeanFactory去getBean。

先根据beanName拿到RootBeanDefinition,然后递归解析bean的所有依赖,朋友们可以想一下这个过程,最后保证当前所有的依赖都已经创建了,然后开始准备创建当前bean。

可以看到创建bean的工作委托给了createBean,这个方法在子类AbstractAutowireCapableBeanFactory中实现:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
...
// 真正创建bean的类
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
...
}

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
... // 省略了其他代码
instanceWrapper = createBeanInstance(beanName, mbd, args);
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
...
}

/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

这里就非常清晰了:

首先委托给了真正的创建方法:doCreateBean

doCreateBean实例化Bean分三步走:

  1. doCreateBean中首先调用createBeanInstance实例化Bean,这个时候Bean被实例化了。createBeanInstance中根据各种不同的配置,采用不同的构造函数进行实例化。

  2. doCreateBean中然后调用populateBean方法,改方法将Bean的各种依赖通过BeanWrapper提供的对属性的编辑方法,设置到Bean中。这一步完成了Bean的依赖的组装。

  3. doCreateBean最后调用了initializeBean,意为初始化Bean,这个时候的Bean已经是一个Object实例,并且Bean中通过@Autowire设置的依赖也全部设置完毕。但是最后还有一些初始化工作要做,看代码:首先,如何这个Bean实现了各种Aware接口,则依次调用这些接口的set方法设置信息;然后调用所有的BeanPostProcessors中的Before方法;然后调用通过”init-method”指定的init方法;最后调用所有BeanPostProcessors中的After方法。

最后,这些方法一层一层向上返回了初始化完成的Bean实例。

返回到AbstractBeanFactory中后调用了getObjectForBeanInstance(),检查返回的Bean Instance是否是FactoryBean,如果是,则调用getObject方法获取真正的实例。

创建完后的Bean会放进各种Map中,前面已经讲过了,下次再次getBean的时候,就是从缓存中获取了。

三. 总结

我们没有讲Spring是怎么扫描并将各种标注了@Service的Class转换成BeanDefinition的,上面的过程是在所有的BeanDefinition已经生成并存储在内存中之后执行的。BeanFactory有一个实现类叫做XmlBeanFactory,虽然已经被遗弃了,但是里面展示了如何将application.xml中定义的Bean转化成BeanDefinition的过程,这些都不是这篇文章的重点。这篇文章重点讲解了BeanFactory的每一级继承结构,以及调用getBean的时候发生了什么,Bean的实例是如何被创建并返回的,Aware接口是什么时候被调用的。

在代码中我们可以清晰的看到一个bean被初始化的生命周期:实例化->组装各种依赖->调用Aware接口方法->调用BeanPostProcessor的before方法->指定的”init-method”方法->调用BeanPostProcessor的after方法。关于生命周期,《Spring In Action》这本书中有详细讲解。

其实到这里spring-beans模块的核心部分就已经讲完了,里面还有一些接口如:Aware、InitializingBean、DisposableBean、BeanReference等,这些都是常用接口,但是这些接口没啥好讲的,都是基于实践意义上的接口。关于RootBeanDefinition和ChildBeanDefinition是如何合并的这里也没有多说,比较简单,基于java的继承和多态机制仿的一个工能,所以也不说了。

之后可能会讲一讲spring-context包和spring-mvc包中的一些常用接口,但是我认为spring的灵魂部分,到这里算是讲完了。

其实究其本质呢,bean的初始化底层依赖两个工具,那就是反射和自省,用反射实例化Bean以及调用一些方法(如init-method),用自省去设置Bean的各种属性。中间做的各种工作,都是对这两个底层调用的封装,BeanWrapper就是对自省功能的封装,BeanDefinition是对Bean的设置,BeanFactory是对反射功能的封装。

除了spring的主体功能之外,还有异常的封装、log的打印等都是值得好好研究和学习的地方,以后有时间我也会给朋友们写一写。

如果文章中有任何不对的地方,请您不吝赐教,也欢迎加我微信交流~