欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

spring5源码解析—Bean的获取流程

程序员文章站 2024-01-11 16:25:46
Bean的获取分为是否在Bean中加了@lazy注解正常加载的流程调用getBean()后第一步会进入AbstractApplicationContext中的getBean方法,此方法会返回一个getBeanFactory().getBean(name),其中name是getBean时传入的@Overridepublic Object getBean(String name) throws BeansException {assertBeanFactoryActive();r...

Bean的获取分为是否在Bean中加了@lazy注解

正常加载的流程

调用getBean()后第一步会进入AbstractApplicationContext中的getBean方法,此方法会返回一个getBeanFactory().getBean(name),其中name是getBean时传入的

 @Override
	public Object getBean(String name) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name);
	}

接下来进入getBeanFactory().getBean(name)中,我们可以发现此方法是调用了AbstractBeanFactory中的getBean方法,并返回一个doGetBean方法

 @Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

继续进入这个doGetBean,可以发现该方法也是在AbstractBeanFactory中,这个方法非常长,我们先看一部分。

 @SuppressWarnings("unchecked")
	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		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 + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

...... 

第一步会执行一个 transformedBeanName(name),这个方法是判断传入的Bean的name是否以&开头,如果不是就使用当前的name,如果是就会返回一个BeanFactory的beanName

 public static String transformedBeanName(String name) {
		Assert.notNull(name, "'name' must not be null");
        //BeanFactory.FACTORY_BEAN_PREFIX ==  &
		if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
			return name;
		}
		return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
			do {
				beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
			}
			while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
			return beanName;
		});
	}

第二步会执行DefaultSingletonBeanRegisty类中的getSingleton(beanName),该方法是为了判断这个bean是否已经有缓存了

public Object getSingleton(String beanName) {
	return getSingleton(beanName, true);
}

我们具体来看这个方法是如何实现的

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //根据beanName得到一个单例对象
		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;
}

如果是正常情况,singletonObject 是不会为空的,所以会创建出singletonObject对象并返回,所以我们回到doGetBean方法

@SuppressWarnings("unchecked")
protected <T> T doGetBean(
		String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
		throws BeansException {

	// Eagerly check singleton cache for manually registered singletons.
	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 + "'");
				}
		}
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

            ...... 

也就是说在有缓存的情况下doGetBean方法中getSingleton(beanName)会返回一个单例对象,并赋值给sharedInstance

接着会判断sharedInstance != null && args == null,其中args就是判断你除了给bean的name之外还有没有带其他参数,不在我们讨论范围内,因此会直接跳到getObjectForBeanInstance方法

这个方法在AbstractAutowireCapableBeanFactory类下

@Override
protected Object getObjectForBeanInstance(
		Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

	String currentlyCreatedBean = this.currentlyCreatedBean.get();
	if (currentlyCreatedBean != null) {
		registerDependentBean(beanName, currentlyCreatedBean);
	}

	return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}

他在return中继续调用了AbstractBeanFactory中的getObjectForBeanInstance方法,在这里会判断这个实例到底是哪个对象的实例,最后返回一个object,就是我们调用getBean方法最终得到的结果。

 protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		// Don't let calling code try to dereference the factory if the bean isn't a factory.
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
			if (mbd != null) {
				mbd.isFactoryBean = true;
			}
			return beanInstance;
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
		if (!(beanInstance instanceof FactoryBean)) {
			return beanInstance;
		}

		Object object = null;
		if (mbd != null) {
			mbd.isFactoryBean = true;
		}
		else {
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

懒加载的流程

懒加载的流程直到getSingleton获取缓存之前都一样,所以直接从这里开始

Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {//这里是false,没有缓存了

}
else {
		 //判断这个bean是否正在创建
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

             //判断当前BeanFactory是否为空
		BeanFactory parentBeanFactory = getParentBeanFactory();
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                //.....
		}

    
		if (!typeCheckOnly) {
                 //为bean标记为已经创建
		    markBeanAsCreated(beanName);
		}

		
}

首先会判断这个bean是否正在创建,如果是正在创建的话会抛出BeanCurrentlyInCreationException异常

然后判断BeanFactory是否为空,是为了判断这个bean是否已经在BeanFactory中定义了,只是还没生产出来,这是为了防止多线程的问题。

接着要为bean做一个标记,来看一下这个markBeanAsCreated方法

 protected void markBeanAsCreated(String beanName) {
		if (!this.alreadyCreated.contains(beanName)) {
			synchronized (this.mergedBeanDefinitions) {
				if (!this.alreadyCreated.contains(beanName)) {
					// Let the bean definition get re-merged now that we're actually creating
					// the bean... just in case some of its metadata changed in the meantime.
					clearMergedBeanDefinition(beanName);
					this.alreadyCreated.add(beanName);
				}
			}
		}
	}

Spring在这里会进行了加锁的双重验证(double Check)判断这个bean是否已经被标记为创建了,如果没有还会再清空一次

clearMergedBeanDefinition(beanName),不得不说,真是相当保险,然后才会标记为已经创建。

接下来是这个else中的下半部分。

try {
			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) {
                			destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {

				}

		    }
}

在这里首先执行getMergedLocalBeanDefinition(beanName)方法获取这个bean中所有的定义,例如是否懒加载、是否多例、是否自动注入等等

接下来分别是判断这个bean有无依赖、单例还是多例,因为这里是单例的,所以进入到这个方法中

// Create bean instance.
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);
}

在这里他再次调用DefaultSingletonBeanRegisty另一个getSingleton方法,

 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
                    .........
                    ........
				if (newSingleton) {
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

调用其中的addSingleton方法,将bean和singletonObejct的放入map中,然后注册。

 protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

然后返回一个singletonObject,并赋值给外层的sharedInstance

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);
}

最后又调用了我们熟悉的AbstractBeanFactory中的getObjectForBeanInstance方法,在这里会判断这个实例到底是哪个对象的实例,最后返回一个object,就是我们调用getBean方法最终得到的结果。

 protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		// Don't let calling code try to dereference the factory if the bean isn't a factory.
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
			if (mbd != null) {
				mbd.isFactoryBean = true;
			}
			return beanInstance;
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
		if (!(beanInstance instanceof FactoryBean)) {
			return beanInstance;
		}

		Object object = null;
		if (mbd != null) {
			mbd.isFactoryBean = true;
		}
		else {
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	} 

本文地址:https://blog.csdn.net/qq_42341656/article/details/107896328

相关标签: spring java Bean