Spring 5 AbstractBeanFactory -- getObjectForBeanInstance 源码解析

相关源码注释

ApplicationContext

Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释

BeanFactory

Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释

getObjectForBeanInstance(sharedInstance, name, beanName, null);

从 beanInstannce 中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是FactoryBean会直接 返回beanInstance实例

/**
	 * Get the object for the given bean instance, either the bean
	 * instance itself or its created object in case of a FactoryBean.
	 * <p>获取给定Bean实例对象,对于FactoryBean,可以是Bean实例本身,也可以
	 * 是它创建的对象</p>
	 * @param beanInstance the shared bean instance - 共享bean实例
	 * @param name name that may include factory dereference prefix - 可能包含工厂取消引用前缀的名字
	 * @param beanName the canonical bean name - 规范bean名
	 * @param mbd the merged bean definition - 合并的bean定义
	 * @return the object to expose for the bean - 为bean公开的对象
	 */
	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.
		// 如果Bean不是工厂,不要让调用代码尝试取消对工厂的引用
		// 如果 name为FactoryBean的解引用.name是以'&'开头,就是FactoryBean的解引用
		if (BeanFactoryUtils.isFactoryDereference(name)) {
    
    
			//如果beanInstance是NullBean实例
			if (beanInstance instanceof NullBean) {
    
    
				//返回beanInstance
				return beanInstance;
			}
			//如果beanInstance不是FactoryBean实例
			if (!(beanInstance instanceof FactoryBean)) {
    
    
				//抛出Bean不是一个Factory异常
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
			//如果mbd不为null
			if (mbd != null) {
    
    
				//设置mbd是否是FactoryBean标记为true
				mbd.isFactoryBean = true;
			}
			//返回beanInstance
			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.
		// 现在我们有了Bean实例,他可能是一个普通的Bean或FactoryBean。
		// 如果它是FactoryBean,我们使用它来创建一个Bean实例,除非调用者确实需要对工厂的引用。
		//如果beanInstance不是FactoryBean实例
		if (!(beanInstance instanceof FactoryBean)) {
    
    
			return beanInstance;
		}
		//定义为bean公开的对象,初始化为null
		Object object = null;
		//如果mbd不为null
		if (mbd != null) {
    
    
			//更新mbd的是否是FactoryBean标记为true
			mbd.isFactoryBean = true;
		}
		else {
    
    
			//从FactoryBean获得的对象缓存集中获取beanName对应的Bean对象
			object = getCachedObjectForFactoryBean(beanName);
		}
		//如果object为null
		if (object == null) {
    
    
			// Return bean instance from factory.
			// 从工厂返回Bean实例
			//将beanInstance强转为FactoryBean对象
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			// 如果是单例对象,则缓存从FactoryBean获得的对象、
			//如果mbd为null && 该BeanFactory包含beanName的BeanDefinition对象。
			if (mbd == null && containsBeanDefinition(beanName)) {
    
    
				//获取beanName合并后的本地RootBeanDefintiond对象
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			//是否是'synthetic'标记:mbd不为null && 返回此bean定义是否是"synthetic"【一般是指只有AOP相关的prointCut配置或者
			// 		Advice配置才会将 synthetic设置为true】
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			//从BeanFactory对象中获取管理的对象.如果不是synthetic会对其对象进行该工厂的后置处理
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		//返回为bean公开的对象
		return object;
	}

BeanFactoryUtils.isFactoryDereference(name)

返回给定名称是否为FactoryBean的解引用.判断依据:name是以’&'开头,就是FactoryBean的解引用

/**
	 * Return whether the given name is a factory dereference
	 * (beginning with the factory dereference prefix).
	 * <p>返回给定名称是否为FactoryBean的解引用名.(从FactoryBean的解引用前缀开始)</p>
	 * @param name the name of the bean -- bean名
	 * @return whether the given name is a factory dereference -- 给定名称是否为BeanFactory的解引用
	 * @see BeanFactory#FACTORY_BEAN_PREFIX
	 */
	public static boolean isFactoryDereference(@Nullable String name) {
    
    
		//如果有传入bean名且bean名是以'&'开头,则返回true,表示是BeanFactory的解引用,否则
		// 返回false,表示不是BeanFactory的解引用
		return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
	}

getCachedObjectForFactoryBean(beanName)

org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getCachedObjectForFactoryBean(String beanName)
从FactoryBean获得的对象缓存集中获取beanName对应的Bean对象

/**
	 * Cache of singleton objects created by FactoryBeans: FactoryBean name to object.
	 * <p>由FactoryBeans创建的单例对象的缓存:FactoryBean名称到对象</p>
	 * */
	private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
	
/**
	 * Obtain an object to expose from the given FactoryBean, if available
	 * in cached form. Quick check for minimal synchronization.
	 * <p>获取要从给定的FactoryBean公开的对象(如果以缓存的形式可用)。快速检查最小
	 * 同步</p>
	 * @param beanName the name of the bean -- bean名
	 * @return the object obtained from the FactoryBean,
	 * or {@code null} if not available
	 * 	-- 从FactoryBean获得的对象;如果不可用,则为null
	 */
	@Nullable
	protected Object getCachedObjectForFactoryBean(String beanName) {
    
    
		return this.factoryBeanObjectCache.get(beanName);
	}

containsBeanDefinition(beanName)

org.springframework.beans.factory.support.AbstractBeanFactory # containsBeanDefinition(String beanName) 是个抽象方法:

/**
	 * Check if this bean factory contains a bean definition with the given name.
	 * Does not consider any hierarchy this factory may participate in.
	 * Invoked by {@code containsBean} when no cached singleton instance is found.
	 * <p>该BeanFactory是否包含beanName的BeanDefinition对象。不考虑工厂可能参与的任何层次结构。
	 * 未找到缓存的单例实例时,由{@code containsBena}调用。</p>
	 * <p>Depending on the nature of the concrete bean factory implementation,
	 * this operation might be expensive (for example, because of directory lookups
	 * in external registries). However, for listable bean factories, this usually
	 * just amounts to a local hash lookup: The operation is therefore part of the
	 * public interface there. The same implementation can serve for both this
	 * template method and the public interface method in that case.
	 * <p>根据具体bean工厂实现的性质,此操作可能很昂贵(例如,由于在外部注册表中进行目录
	 * 寻找)。但是,对应可列出的bean工厂,这通常只相当于本地哈希查找:因此,该操作是该处
	 * 工厂接口的一部分。在这种情况下,该模板方法和公共接口方法都可以使用相同的实现。</p>
	 * @param beanName the name of the bean to look for - 要查找的bean名
	 * @return if this bean factory contains a bean definition with the given name
	 *  - 如果此bean工厂包含具有给定名称的bean定义。
	 * @see #containsBean
	 * @see org.springframework.beans.factory.ListableBeanFactory#containsBeanDefinition
	 */
	protected abstract boolean containsBeanDefinition(String beanName);

由 DefaultListableBeanFactory 实现:

	/**
	 * Map of bean definition objects, keyed by bean name.
	 * <p>Bean定义对象的映射,以Bean名称为键</p>
	 * */
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

/**
	 * 本地工厂中BeanDefinition对象映射【beanDefinitionMap】中是否存在beanName该键名
	 * @param beanName the name of the bean to look for -- 要寻找的bean名
	 */
	@Override
	public boolean containsBeanDefinition(String beanName) {
    
    
		//如果beanName为null,抛出异常
		Assert.notNull(beanName, "Bean name must not be null");
		//从Beand定义对象映射中判断beanName是否存在该键
		return this.beanDefinitionMap.containsKey(beanName);
	}

getMergedLocalBeanDefinition(beanName)

获取beanName合并后的本地RootBeanDefintiond

Spring 5 AbstractBeanFactory – getMergedLocalBeanDefinition 源码解析

getObjectFromFactoryBean(factory, beanName, !synthetic)

从BeanFactory对象中获取管理的对象.可根据shouldPostProcess对其对象进行该工厂的后置处理

Spring 5 AbstractBeanFactory – getObjectFromFactoryBean 源码解析

猜你喜欢

转载自blog.csdn.net/qq_30321211/article/details/108335927