Spring源码分析(3)——Bean实例化代码分析

分析Spring Bean实例化代码,探究Bean是如何被Spring实例化的

一、Bean的实例化代码分析

先看下面Spring实例化bean的代码,通过参数beanName、BeanDefinition、args来实例化bean,包含以下几步:

  • 如果存在factoryMethodName属性,或者说在配置文件中配置了factory-method,那么直接使用该构造函数生成bean

  • 使用已经解析并缓存好的构造函数实例化

  • 使用有参构造函数或无参构造函数实例化bean

AbstractAutowireCapableBeanFactory.java
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
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);

if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowe()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}

Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}

if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}

// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}

// Need to determine the constructor...
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//使用有参构造函数实例化
return autowireConstructor(beanName, mbd, ctors, args);
}

//使用无参构造函数实例化
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}

无论是有参构造函数还是无参构造函数,都会寻找一个构造函数来实例化,只是有参构造函数的寻找十分复杂,下面以无参构造函数的实例化代码举例。

根据代码中instantiate()方法继续向下跟踪到BeanUtils#instantiateClass()的方法中,可以十分明显的看到ctor.newInstance(args)方法的调用,使用反射实例化bean的本质一览无遗。

AbstractAutowireCapableBeanFactory.java
1
2
3
4
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
......
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
......

SimpleInstantiationStrategy.java
1
2
3
4
5
6
7
8
9
10
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
......
{
return BeanUtils.instantiateClass(constructorToUse);
} else {
//使用CGLIB来实例化对象
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
......
BeanUtils.java
1
2
3
4
5
6
7
8
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
......

二、结论

Spring对于普通单例bean的实例化,采用的是反射调用构造函数实现的。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×