Spring Bean生成
1.目标
自然是来看看spring的bean生成流程的源码
但是这流程就算不关注大量细节,也真的很长,后面考虑把这一篇再拆一拆
2.查找入口
private static void testSpring() {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml");
Object alice = context.getBean("alice");
System.out.println(alice);
}
断点打在getBean来看看
下面的代码会来到AbstractApplicationContext
还记得之前讨论过的BeanFactory继承体系和它们的作用吗?可以看看第2篇和第3篇。
public Object getBean(String name) throws BeansException {
//空实现
assertBeanFactoryActive();
//通过BeanFactory创建bean
return getBeanFactory().getBean(name);
}
接着到了AbstractBeanFactory
是不是很熟悉呢
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
看见了doGetBean入口算是找到了
3.bean加载
乍一看下面的代码估计是很懵的状态,我们先来梳理下它到底干了什么再来深入其中的各个方法:
-
剥离工厂方法中真实的beanName,将alias转换为大名
简单点说这一步就是为了获取到bean真名
-
创建前在缓存中获取bean,若获取到了就调用
getObjectForBeanInstance
获取真正的bean(前面有可能的是FactoryBean),返回bean;如果没有获取到进入步骤3 -
先检查先是否是Prototype scope正在创建的bean,如果是假设其存在循环依赖,直接抛异常
-
检查本BeanFactory是否有所需bean的
BeanDefinition
若没有交给parentBeanFactory解决bean的创建,如果有所需BeanDefiniton
进入步骤5 -
获取
BeanDefinition
,检查其dependOn是否存在循环依赖。记录其依赖信息,先创建(getBean)它依赖的bean -
分为singleton单例、prototype原型以及其他scope 3种来创建bean
-
如果是singleton就通过
getSingleton(String beanName, ObjectFactory<?> singletonFactory)
,产生原始bean,再通过getObjectForBeanInstance
获取真正的bean。ps:这里的ObjectFactory
我们会在后面讨论spring解决单例属性注入循环依赖时再细说; -
如果是prototype使用
createBean
来创建bean,在这个方法前后有对应callback接口的处理。同样的再通过getObjectForBeanInstance
获取真正的bean -
如果是其他scope,先获取Scope对象然后通过其
get(String name, ObjectFactory<?> objectFactory)
方法获取bean,通过getObjectForBeanInstance
获取真正的bean -
最终返回bean
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
//1. 获取bean的真名
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 2.获取bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//获取真正的bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 3.先检查先是否是Prototype scope正在创建的bean,如果是直接抛异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
// 4.检查本BeanFactory是否有所需bean的`BeanDefinition`,若没有,交给parentBeanFactory解决bean的创建
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//5.获取beanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 5.保证要生成bean依赖的bean先生成
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);
getBean(dep);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
//7.创建Singleton scope bean
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return createBean(beanName, mbd, args);
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
//8.创建prototype scope bean
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
//其他scope的bean创建
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
return (T) bean;
}
好了梳理了AbstractBeanFactory
的doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
我们接下来关注下面的几个方法实现
- getSingleton
- getObjectForBeanInstance
- createBean
- scope的
get(String name, ObjectFactory<?> objectFactory)
3.1 getSingleton
在理解这个方法之前我们需要先了解3个缓存
- singletonObjects用来缓存单例bean
- earlySingletonObjects用来缓存早期的bean,就是还没有完成依赖注入的
- singletonFactories单例bean的ObjectFactory缓存
为什么要有这3个缓存呢?主要还是为了解决前面提到过的循环依赖问题。安装下面缓存调用的顺序singletonObjects->earlySingletonObjects->singletonFactories也有地方把它们称为3级缓存
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);
接下来我们先读从缓存中获取单例bean,既然是从缓存中获取自然涉及到上面提及的3个缓存了。singletonObjects->earlySingletonObjects->singletonFactories按照这样的顺序,如果没有获取到想要的bean就要看看它的重载方法(AbstractBeanFactory
流程)
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory =
this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
下面是getSingleton
的重载方法,从头加载bean。其实这个方法逻辑也很简单。流程有以下几步
-
尝试从缓存获取,获取到就返回
-
获取不到准备创建,先处理create前置方法
-
通过ObjectFactory来创建bean
-
先处理create后置方法
-
添加bean到缓存
-
返回bean
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
//1.尝试从缓存获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//2.获取不到准备创建,先处理create前置方法
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
//3. 通过ObjectFactory来创建bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//4.先处理create后置方法
afterSingletonCreation(beanName);
}
if (newSingleton) {
//5. 添加bean到缓存
addSingleton(beanName, singletonObject);
}
}
//6. 返回bean
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
到现在我们还在bean创建的控制流程中兜转,不过看到ObjectFactory.getObject算是看到了希望。这里大家知道前面AbstractBeanFactory对于这个接口实现的作用了吧。而BeanFactory的实现也很简单
new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return createBean(beanName, mbd, args);
}
到这里我们可以把singleton和prototype的bean创建统合起来了,都是有create前后的处理+createBean
3.2 createBean
真正的准备创建来了(按spring的方法命名规律看到do才是真的创建),满怀欣喜的点进去一看AbstractBeanFactory
并没有实现这个方法,想一想第3篇的实现,createBean方法的实现放在哪了?当然大家直接debug看会看的更清楚
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException;
跳到AbstractAutowireCapableBeanFactory
,一如既往的保持spring的风格,这个方法内容不多,这里只关注下doCreateBean
真正的创建bean
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;