写在前面
在spring IOC注册BeanDefinition
中已经完成了BeanDefinition向spring的map缓存中注册的工作,本文接着分析spring是如何通过beandefinition来初始化bean对象的。只看源码的话比较枯燥,对应的流程图版本可以参考这里。
1:测试使用代码
1.1:使用的bean
public class BookService {
}
1.2:xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bookService" class="yudaosourcecode.constructorarg.BookService"/>
</beans>
1.3:测试代码
@Test
public void testGetBean() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("testbeandefinition.xml");
BookService bookService = ac.getBean("bookService", BookService.class);
System.out.println(bookService);
}
运行:
yudaosourcecode.constructorarg.BookService@670b40af
Process finished with exit code 0
我们就从代码ac.getBean("bookService", BookService.class);
开始看起吧!
2:getBean
先调用的是org.springframework.beans.factory.BeanFactory
容器顶层接口的子类AbstractApplicationContext
,源码:
org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.String, java.lang.Class<T>)
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
// <2021-03-10 09:20>
assertBeanFactoryActive();
// <2021-03-10 09:21>
return getBeanFactory().getBean(name, requiredType);
}
<2021-03-10 09:20>
处是检测bean工厂容器的活跃性,源码:
org.springframework.context.support.AbstractApplicationContext#assertBeanFactoryActive
protected void assertBeanFactoryActive() {
// this.active定义为private final AtomicBoolean active = new AtomicBoolean();
// 若为false,则继续判断是否关闭
if (!this.active.get()) {
// this.closed定义为private final AtomicBoolean closed = new AtomicBoolean();
// 若为true则抛出异常,给出已经关闭的信息
if (this.closed.get()) {
throw new IllegalStateException(getDisplayName() + " has been closed already");
}
// 若为false,说明没有关闭,给出容器还没有进行刷新的异常信息
else {
throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
}
}
}
<2021-03-10 09:21>
处getBeanFactory()
调用的是BeanFactory顶层容器接口的子类AbstractRefreshableApplicationContext
,源码:
org.springframework.context.support.AbstractRefreshableApplicationContext#getBeanFactory
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized (this.beanFactoryMonitor) {
// 如果是为null,说明已经关闭或者是容器还没有刷新
// 给出相关的异常信息
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
// 这里的类型是DefaultListableBeanFacotry
return this.beanFactory;
}
}
<2021-03-10 09:21>
的getBean调用的是AbstractBeanFactory的方法,源码:
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Class<T>)
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
继续:
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// <2021-03-10 10:03>
// 获取bean名称,如转换alias为beanName
final String beanName = transformedBeanName(name);
Object bean;
// 从单例缓存中获取bean,单例bean只会创建一次,这里具体的代码体现
Object sharedInstance = getSingleton(beanName);
// 如果是单例bean,if内部会处理FactoryBean,后置bean处理器等逻辑
if (sharedInstance != null && args == null) { // 单例bean的逻辑
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// <2021-03-10 10:17>
// 处理FactoryBean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else { // 原型bean的逻辑
// <2021-03-10 18:41>
// 如果是当前bean已经在创建中,并且是prototype的
// 说明存在prototype的循环依赖,则抛出异常,因为spring只解决singleton的循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// <2021-03-11 09:15>
// 如果是后续无法从当前容器获取bean定义,则尝试从父容器中
// 获取
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// <2021-03-11 18:35>
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// <2021-03-11 18:39>
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// <2021-03-11 18:45>
checkMergedBeanDefinition(mbd, beanName, args);
// <2021-03-13 10:17>
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 因为当前beanName是depend-on dep的
// 如果是dep也depend-on beanName,则异常
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);
}
}
}
// <2021-03-13 10:29>
// bean的实例化,分为单例singleton,原型prototype分别处理
if (mbd.isSingleton()) { // 单例模式
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) { // 原型模式
// 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
String scopeName = mbd.getScope();
// this.scopes是一个"scope名称->Scope对象"的map
final Scope scope = this.scopes.get(scopeName);
// 如果没有获取到scope则异常,因为创建bean需要依赖于其scope
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// <2021-03-13 10:50>
// 检查需要的类型是否符合实际的类型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
<2021-03-10 10:03>
获取最终要初始化的beanName,具体参考2.1:transformedBeanName转换bean名称
,<2021-03-10 10:17>
处是从单例缓存中获取bean,并进行FactoryBean的相关处理,具体参考2.2:getObjectForBeanInstance
,<2021-03-10 18:41>
处代码是检测prototype的bean存在循环依赖的情况,spring不处理这种情况,具体参考2.3:prototype的bean循环依赖检测
,<2021-03-11 09:15>
处是尝试从父容器中查找bean定义,具体参考2.4:从父容器中查找bean定义
,<2021-03-11 18:35>
处是将bean标记为已创建或者是正在创建中,详细参考2.5:markBeanAsCreated
,<2021-03-11 18:39>
处是通过bean名称获取beandefinition,详细参考2.6:通过bean名称获取bean定义
,<2021-03-11 18:45>
处是检查当前beandefinition是否为抽象bean,抽象bean仅仅用于定义公共信息,不能实例化,源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#checkMergedBeanDefinition
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
throws BeanDefinitionStoreException {
// 如果是抽象的,则异常
if (mbd.isAbstract()) {
throw new BeanIsAbstractException(beanName);
}
}
详细关于抽象bean可以参考spring配置中的abstract,parent分析
,<2021-03-13 10:17>
处是依赖bean的处理,具体参考2.7:依赖bean的处理
,关于依赖bean depend-on可以参考spring如何控制bean的初始化顺序
,<2021-03-13 10:29>
处是初始化不同作用域的bean,具体参考2.8:不同作用域bean的初始化
,<2021-03-13 10:50>
处是检查要求的类型是否和实际的类型一致,如果是不一致的话需要进行类型转换,详细参考2.9:强制类型转换
。
2.1:transformedBeanName转换bean名称
执行如下代码:
org.springframework.beans.factory.support.AbstractBeanFactory#transformedBeanName
protected String transformedBeanName(String name) {
// <2021-03-14 09:17>
// 这里是转换非标准bean名称(别名,工厂bean名称)为标准bean名称
// 1:如果是工厂bean名称去除前面所有的&
// 2:转换1的结果如果是别名则转换为标准bean名称
// 需要注意工厂bean名称也可能存在别名的场景
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
<2021-03-14 09:17>
处transformedBeanName
是去除bean工厂的修饰符&
,关于bean工厂可以参考spring的BeanFactory分析
,源码如下:
org.springframework.beans.factory.BeanFactoryUtils#transformedBeanName
public static String transformedBeanName(String name) {
// 判空
Assert.notNull(name, "'name' must not be null");
// 如果不是以&开头,则不是bean工厂的bean名称,直接返回
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// transformedBeanNameCache定义为:
// Map<String, String> transformedBeanNameCache = new ConcurrentHashMap<>();
// 是一个存储”bean工厂bean名称->实际bean名称“的缓存
// 这里,如果是存在key为name的则直接返回,否则,调用
// conputerIfAbsent的第二个参数,去除&,直到不以&开头就是我们需要的结果了
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
// 返回bean名称,如&&&myBeanName,结果就是myBeanName
return beanName;
});
}
<2021-03-14 09:17>
处canonicalName是转换别名为标准名称,源码:
org.springframework.core.SimpleAliasRegistry#canonicalName
public String canonicalName(String name) {
// 默认使用当前名称作为标准名称
String canonicalName = name;
String resolvedName;
do {
// 从别名map中获取标准bean名称
// 这里循环处理的原因是别名获取的结果可能还是别名,如通过
// alias标签即可以给标准bean名称设置别名,也可以给别名设置
// 别名,如下配置:
/*
<bean id="car" name="car_1,car_2" class="yudaosourcecode.factorybean.CarFactoryBean">
<property name="carInfo" value="超级跑车,400,2000000"/>
</bean>
<alias name="car_1" alias="car_1_1"/>
*/
// 则会有"car_1_1->car_1",”car_1->car“的映射,当通过
// car_1_1获取时就会经过两次转换
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
// 返回标准bean名称
return canonicalName;
}
2.2:getObjectForBeanInstance
该处是bean为单例bean时执行的逻辑,处理FactoryBean相关的内容,源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...snip...
// <2021-03-14 11:34>
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
// 根据是否正在创建中,打印不同的日志信息
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// <2021-03-14 15:23>
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
...snip...
return (T) bean;
}
<2021-03-14 11:34>
处是从单例缓存中获取bean,具体参考2.2.1:从单例缓存中获取bean
,<2021-03-14 15:23>
是处理FactoryBean相关逻辑,具体参考2.2.2:单例bean处理工厂bean逻辑
。
2.2.1:从单例缓存中获取bean
源码:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
继续:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// <2021-03-14 14:26>
Object singletonObject = this.singletonObjects.get(beanName);
// <2021-03-14 14:53>
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// <2021-03-14 15:06>
// 从早期单例对象集合中获取
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果是从早期对象对象map中也没有获取,并且允许提前创建
if (singletonObject == null && allowEarlyReference) {
// 根据bean名称获取用于单例bean创建的对象ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
// 如果是获取到对应单例工厂类,则创建单例对象
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 存放到早期单例对象map中
this.earlySingletonObjects.put(beanName, singletonObject);
// 从单例工厂中移除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
<2021-03-14 14:26>
处代码是从单例缓存中获取对象,缓存如下:
/** beanName->object的单例缓存map */
private final Map<String, Object> singletonObjects
= new ConcurrentHashMap<>(256);
<2021-03-14 14:53>
处如果是没有获取到且正在创建中,其中isSingletonCurrentlyInCreation
源码如下:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#isSingletonCurrentlyInCreation
public boolean isSingletonCurrentlyInCreation(String beanName) {
// private final Set<String> singletonsCurrentlyInCreation
// = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
// 如果是在集合中包含则说明是正在创建中,在第一次getBean处理过程中会放到集合中
return this.singletonsCurrentlyInCreation.contains(beanName);
}
<2021-03-14 15:06>
处earlySingletonObjects
定义如下:
// beanName->instance 的map,不过存储的是早期bean实例,用来辅助解决单例
// bean的循环依赖问题
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
2.2.2:单例bean处理工厂bean逻辑
源码:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 从threadlocal中获取当前正在创建的bean
String currentlyCreatedBean = this.currentlyCreatedBean.get();
// 这里可以认为是false
if (currentlyCreatedBean != null) {
registerDependentBean(beanName, currentlyCreatedBean);
}
// <2021-03-14 15:40>
return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}
<2021-03-14 15:40>
处调用父类处理工厂bean逻辑,源码:
org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// isFactoryDereference方法判断是否以&开头,是则是获取工厂bean本身
// 而非工厂bean生产的对象,即getObject方法返回的对象
if (BeanFactoryUtils.isFactoryDereference(name)) {
// NullBean是spring定义的用来代表null对象的,如果是则直接返回
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 如果不是FactoryBean类型的,则抛出BeanIsNotAFactoryBean
// 异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
}
// 如果不是FactoryBean类型,或者bean名称直接以&开头,则直接返回
// 实例,其中以&开头说明调用者就是希望获取工厂bean本身
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
// 如果bean定义为空,则从工厂bean缓存map中获取
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
// 如果从工厂bean缓存map中也没有获取
if (object == null) {
// 执行到这里就说明一定是BeanFactory了,进行强转
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 如果是bean定义为空,则从bean定义的缓存map中通过bean名称获取bean定义
if (mbd == null && containsBeanDefinition(beanName)) {
// 从bean定义的缓存map中获取bean定义
mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否为用户自定义bd,可以认为是false
boolean synthetic = (mbd != null && mbd.isSynthetic());
// <2021-03-14 16:24>,从工厂bean中获取目标bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
<2021-03-14 16:24>
就是当为工厂bean时通过工厂bean获取对象的逻辑了,源码如下:
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// factory.isSingleton()判断工厂bean是否为单例的,如果没有设置其和
// 普通的bean一样默认也是单例的
// containsSingleton(beanName)判断单例缓存map中是否包含,一般是包含的
if (factory.isSingleton() && containsSingleton(beanName)) {
// 上锁
synchronized (getSingletonMutex()) {
// factoryBeanObjectCache是一个工厂bean名称到其生产的bean的map缓存,首次一般为null,第一次调用getObject后会放进来作为缓存
Object object = this.factoryBeanObjectCache.get(beanName);
// 如果为空,则通过工厂bean获取
if (object == null) {
// <2021-03-14 16:32> 从工厂bean对象获取目标对象
object = doGetObjectFromFactoryBean(factory, beanName);
// 又是缓存获取,可以认为是null
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
// 可以认为进else
if (alreadyThere != null) {
object = alreadyThere;
}
else {
// 如果是需要后置处理
if (shouldPostProcess) {
// 如果单例bean正在创建中,直接返回,而不存储???应该是防止单例bean重复处理吧
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
// <2021-03-14 16:53>标记为该单例bean创建中
beforeSingletonCreation(beanName);
try {
// <2021-03-14 16:56>应用bean的后置处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
// 从正在创建代理缓存中remove
afterSingletonCreation(beanName);
}
}
// 如果在单例中包含,则放到bean工厂名称->实际对象的map缓存中,则下次再获取时就可以直接使用缓存了
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
// 返回
return object;
}
}
// 非单例
else {
// 同<2021-03-14 16:32>,但是因为不是单例,就每次重新获取了
Object object = doGetObjectFromFactoryBean(factory, beanName);
// 需要后置处理
if (shouldPostProcess) {
try {
// 同<2021-03-14 16:56>
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
<2021-03-14 16:32>
处是从工厂bean中获取目标bean,具体参考2.2.3:从工厂bean中获取目标bean
,<2021-03-14 16:53>
处为标记bean为正在创建中,源码:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
<2021-03-14 16:56>
处是应用bean的后置处理器,具体参考2.2.4:应用bean的后置处理器
,关于后置bean处理器的简单用法可以参考spring的BeanPostProcessor分析
。
2.2.3:从工厂bean中获取目标bean
源码:
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#doGetObjectFromFactoryBean
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 {
// 调用工厂bean的getObject方法获取目标对象
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// 没有获取到
if (object == null) {
// 当前工厂bean正在创建中,则抛出异常
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
// 到这就说明通过getObject方法返回的对象为null,则使用定义的NullBean
object = new NullBean();
}
// 返回目标对象
return object;
}
2.2.4:应用bean的后置处理器
关于后置bean处理器的用法可以参考spring的BeanPostProcessor分析
。源码:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 获取所有的后置bean处理器,调用其postProcessAfterInnitialization方法进行后置处理
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
2.3:prototype的bean循环依赖检测
如果是执行到这里,就是说明是代码Object sharedInstance = getSingleton(beanName);
获取到的sharedInstance是null,此时就有以下两种情况:
1:bean是单例的但是还没有初始化
2:bean是原型的
而本处处理的就是2:bean是原型的
的情况下存在循环依赖的情况。
关于spring bean的循环依赖可以参考spring循环依赖分析
。源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#isPrototypeCurrentlyInCreation
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
// this.prototypesCurrentlyInCreation是一个threadlocal
// 存储的是正在创建beanname或者是beanname的set集合
Object curVal = this.prototypesCurrentlyInCreation.get();
// 在当前threadlocal存储有值的情况下
// 1:如果是存储的值和bean名称相等,或者是
// 2:存储的是正在创建的原型bean名称的set集合,且该集合中包含当前bean名称
// 时,就是原型bean正在创建。
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
}
2.4:从父容器中查找bean定义
到这里,要获取的bean到底是单例的还是原型的依然是不确定的,唯一确定的是肯定不是存在循环依赖的原型bean
,因为如果是在2.3:prototype的bean循环依赖检测
中已经异常了,不会执行到这里,看下源码:
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...snip...
else {
...snip...
// 获取父容器
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果是父容器不为空,并且当前容器的beandefinitionmap不存在
// beanname对应的GenericBeanDefinition,则尝试从父容器中获取
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// <2021-03-16 16:13>
// 获取原始bean名称,主要是处理别名
String nameToLookup = originalBeanName(name);
// 以下是根据父容器不同的类型和参数的不同调用父容器
// 不同的方法,其实就是委托
if (parentBeanFactory instanceof AbstractBeanFactory) { // 如果是AbstractBeanFactory类型
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) { // 如果有args参数
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) { // 如果有requiredType
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else { // 否则调用只有beanName参数的方法
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
...snip...
}
return (T) bean;
}
<2021-03-16 16:13>
处是获取原始bean名称,即在beandefinitionmap中注册的名称,源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#originalBeanName
protected String originalBeanName(String name) {
// 获取标准bean名称,在“2.1:transformedBeanName转换bean名称”
// 中已经分析过了
String beanName = transformedBeanName(name);
// 因为在transformedBeanName方法中如果以&开头的会去掉&,
// 这里需要加回去
if (name.startsWith(FACTORY_BEAN_PREFIX)) {
beanName = FACTORY_BEAN_PREFIX + beanName;
}
return beanName;
}
2.5:markBeanAsCreated
该处是如果不仅仅是类型检查时,标记bean为已创建状态,源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...snip...
// 不是仅类型检查
if (!typeCheckOnly) {
// <2021-03-16 18:06>
markBeanAsCreated(beanName);
}
...snip...
return (T) bean;
}
<2021-03-16 18:06>
处是标记bean为已创建,源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#markBeanAsCreated
protected void markBeanAsCreated(String beanName) {
// alreadyCreated是一个set集合,如果不存在说明你还没有创建
if (!this.alreadyCreated.contains(beanName)) {
// 获取同步锁
synchronized (this.mergedBeanDefinitions) {
// <2021-03-16 18:09>
// DCL双重检查
if (!this.alreadyCreated.contains(beanName)) {
// 清空beanName对应的mergedBeanDefinition信息
/*
protected void clearMergedBeanDefinition(String beanName) {
this.mergedBeanDefinitions.remove(beanName);
}
*/
clearMergedBeanDefinition(beanName);
// 添加beanName到已创建的set集合中
this.alreadyCreated.add(beanName);
}
}
}
}
<2021-03-16 18:09>
是DCL双重检查,防止获取锁后检查状态发生变化,具体可以参考基于DCL的单例懒汉模式实现
。
2.6:通过bean名称获取bean定义
如果是执行到这里,就说明,在当前容器的beandenitionmap中存在beanName对应的BeanDefinition对象,源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...snip...
// <2021-03-17 09:16>
// 合并parent的属性如果存在的话
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// <2021-03-17 09:17>
checkMergedBeanDefinition(mbd, beanName, args);
...snip...
}
<2021-03-17 09:16>
处是合并parent中的抽象bean的公共属性,关于抽象bean可以参考spring配置中的abstract,parent分析
,具体参考2.6.1:getMergedLocalBeanDefinition
,<2021-03-17 09:17>
处参考2.6.2:checkMergedBeanDefinition
。
2.6.1:getMergedLocalBeanDefinition
源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// 先从合并父bean公共属性后的mergedBeanDefinitions的map中获取看是否已经存在(因为可能存在其他线程已经合并完毕的情况)
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
// 如果是存在则直接返回
if (mbd != null) {
return mbd;
}
// <2021-03-17 09:21>
// getBeanDefinition(beanName)是从beandefinitionmap中获取bean定义
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
<2021-03-17 09:21>
处源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(java.lang.String, org.springframework.beans.factory.config.BeanDefinition)
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
// 该方法会解析父抽象bean并将相关信息合并到当前beandefinition
// 最终定义一个RootBeanDefinition,详细不再解析
return getMergedBeanDefinition(beanName, bd, null);
}
2.6.2:checkMergedBeanDefinition
org.springframework.beans.factory.support.AbstractBeanFactory#checkMergedBeanDefinition
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
throws BeanDefinitionStoreException {
// 检测bean如果是抽象的则直接异常,因为抽象bean不能实例化
if (mbd.isAbstract()) {
throw new BeanIsAbstractException(beanName);
}
}
2.7:依赖bean的处理
这里处理的是depend-on
的情况,详细可以参考spring如何控制bean的初始化顺序
。源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...snip...
// 获取通过depend-on配置的依赖bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 循环所有的依赖bean
for (String dep : dependsOn) {
// 当前beanName depend-on dep
// 如果时dep也depend-on beanName,则存在循环depend-on
// 直接异常
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// <2021-03-17 17:43>
registerDependentBean(dep, beanName);
try {
// 加载被depend-on的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
...snip...
}
<2021-03-17 17:43>
是注册依赖关系,源码如下:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerDependentBean
public void registerDependentBean(String beanName, String dependentBeanName) {
// 获取标准名称
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
// 如果是存在key为canonicalName的数据,则返回
// 否则put以canonicalName为key,以new LinkedHashSet<>(8)
// 为value的数据,并返回new LinkedHashSet<>(8)
// dependentBeanMap存储的是"被依赖bean->依赖自己的bean集合"
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
// 添加依赖的bean名称
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
synchronized (this.dependenciesForBeanMap) {
// 同上逻辑
// dependenciesForBeanMap存储的是"bean->自己依赖的bean集合"
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
// 添加当前存在依赖的bean到集合中
dependenciesForBean.add(canonicalName);
}
}
2.8:不同作用域bean的初始化
所有的准备工作,检测工作等做完之后,到这里就是要开始bean的初始化了,源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...snip...
// 根据bean的不同的scope来进行初始化
if (mbd.isSingleton()) { // scope为singleton的初始化
// <2021-03-18 11:25>,创建单例bean
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 可能存在单例循环依赖场景bean已经存在的情况
// 所以这里需要销毁
destroySingleton(beanName);
throw ex;
}
});
// 该处是处理FactoryBean相关内容,在"2.2:getObjectForBeanInstance"已经进行了分析
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// <2021-03-18 13:41> 原型模式创建bean
else if (mbd.isPrototype()) { // scope为prototype的初始化
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
// 该处是处理FactoryBean相关内容,在"2.2:getObjectForBeanInstance"已经进行了分析
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// <2021-03-18 14:26>
else { // 其他作用于,如web环境中的request,session等
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
...snip...
}
<2021-03-18 11:25>
处是创建单例bean,具体参考2.8.1:单例map缓存无时创建单例bean
,<2021-03-18 13:41>
处参考2.8.3:创建原型bean
,<2021-03-18 14:26>
处参考2.8.4:其他scope bean的创建
。
2.8.1:单例map缓存无时创建单例bean
源码如下:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
// 断言判断
Assert.notNull(beanName, "Bean name must not be null");
// 使用单例缓存map上锁,防止多线程操作出现问题
synchronized (this.singletonObjects) {
// 因为当执行到这里时其他线程可能已经初始化了bean,
// 所以这里必须检查一下,保证"singleton"语义的准确性
Object singletonObject = this.singletonObjects.get(beanName);
// 为空才创建,DCL双重检查锁
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// <2021-03-18 12:57>
beforeSingletonCreation(beanName);
// 标记
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// <2021-03-18 13:03>,调用singletonFactory入参的getObject方法
// 创建单例bean
singletonObject = singletonFactory.getObject();
// 创建单例bean完毕,修改标记
newSingleton = true;
}
catch (IllegalStateException ex) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// <2021-03-18 13:06>
afterSingletonCreation(beanName);
}
// <2021-03-18 13:14>
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
<2021-03-18 12:57>
处代码是创建单例bean前做一些前置的准备工作,代码如下:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation
protected void beforeSingletonCreation(String beanName) {
// 添加到当前正在创建的单例bean的set集合中,如果是添加不成功
// 则说明已经存在了,抛出BeanCurrentlyInCreatetion异常
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
<2021-03-18 13:03>
处调用的是入参中的ObjectFactory参数的实现类的getObject方法具体参看2.8.2:通过ObjectFactory的getObject创建单例
。<2021-03-18 13:06>
处是创建单例bean后处理,源码如下:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#afterSingletonCreation
protected void afterSingletonCreation(String beanName) {
// 从正在创建的单例bean的set集合中删除,如果是删除失败
// 则说明bean当前不在创建中,抛出IllegalStateException异常
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
<2021-03-18 13:14>
成功创建单例bean后记录bean的已创建的状态,源码如下:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 添加到单例bean的map缓存中
this.singletonObjects.put(beanName, singletonObject);
// 删除beanName和对应的ObjectFactory,其中ObjectFactory
// 是用于创建单例bean的工厂
this.singletonFactories.remove(beanName);
// 删除beanName->早期bean的对应关系
// 该map是解决单例bean循环依赖的关键
this.earlySingletonObjects.remove(beanName);
// 添加beanName到已注册的单例bean的set集合中
this.registeredSingletons.add(beanName);
}
}
2.8.2:通过ObjectFactory的getObject创建单例
具体参考3:bean具体创建过程
。
2.8.3:创建原型bean
再贴下源码:
else if (mbd.isPrototype()) { // scope为prototype的初始化
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// <2021-03-18 13:43>
beforePrototypeCreation(beanName);
// <2021-03-18 13:52>
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// <2021-03-18 13:53>
afterPrototypeCreation(beanName);
}
// 该处是处理FactoryBean相关内容,在"2.2:getObjectForBeanInstance"已经进行了分析
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
<2021-03-18 13:43>
处是创建原型bean做一些前置准备工作,源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#beforePrototypeCreation
protected void beforePrototypeCreation(String beanName) {
// 从threadlocal中获取值
Object curVal = this.prototypesCurrentlyInCreation.get();
// 如果是没有值,则将当前的设置进去
if (curVal == null) {
this.prototypesCurrentlyInCreation.set(beanName);
}
// 如果是已经存在,并且类型是String则再创建set将已存在的
// 和自己放到set集合中,然后重新将set集合放到threadlocal中
else if (curVal instanceof String) {
Set<String> beanNameSet = new HashSet<>(2);
beanNameSet.add((String) curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
}
// 到这里说明已经是set了,直接add即可
else {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.add(beanName);
}
}
<2021-03-18 13:52>
处比较重要,是创建原型bean了,我现在也没详细看,等看了在分析。<2021-03-18 13:53>
是原型bean创建后的处理,源码如下:
org.springframework.beans.factory.support.AbstractBeanFactory#afterPrototypeCreation
protected void afterPrototypeCreation(String beanName) {
// 从threadlocal中获取值
Object curVal = this.prototypesCurrentlyInCreation.get();
// 如果是String则直接从threadlocal中删除
if (curVal instanceof String) {
this.prototypesCurrentlyInCreation.remove();
}
// 如果是set则强转set,然后从set中删除
else if (curVal instanceof Set) {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.remove(beanName);
// 如果是set已经空了,则从threadlocal中删除
if (beanNameSet.isEmpty()) {
this.prototypesCurrentlyInCreation.remove();
}
}
}
2.8.4:其他scope bean的创建
源码如下:
// 获取scope的名称
String scopeName = mbd.getScope();
// 根据名称获取scope实例
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 通过scope获取实例
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
// 进行FactoryBean相关处理
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
2.9:强制类型转换
当requiredType参数不为空,是会执行该处逻辑进行强转,对应的getBean的重载版本如下:
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
强转源码如下:
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
3:bean具体创建过程
鉴于本文已经比较长,我们单起一篇文章来分析这个过程,具体参考bean具体创建过程分析。