Spring 5 AbstractBeanFactory -- createBean 源码解析(二)

58 篇文章 1 订阅
56 篇文章 3 订阅

Spring 5 AbstractBeanFactory – createBean 源码解析(一)
Spring 5 AbstractBeanFactory – createBean 源码解析(二)

相关源码注释

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 源码注释

getEarlyBeanReference(beanName, mbd, bean)

该方法由 ObjectFactory实例的 getObject 方法 调用

/**
	 * Obtain a reference for early access to the specified bean,
	 * typically for the purpose of resolving a circular reference.
	 * <p>获取对 指定Bean 的 早期访问引用,通常用于解决循环引用</p>
	 * @param beanName the name of the bean (for error handling purposes) -- bean的名称(用于处理错误)
	 * @param mbd the merged bean definition for the bean -- 合并后的BeanDefinition对象
	 * @param bean the raw bean instance -- 原始Bean实例
	 * @return the object to expose as bean reference -- 要公开为bean引用的对象
	 */
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		//默认最终公开的对象是bean
		Object exposedObject = bean;
		//mbd的systheic属性:设置此bean定义是否是"synthetic",一般是指只有AOP相关的prointCut配置或者Advice配置才会将 synthetic设置为true
		//如果 mdb不是syntheic 且 此工厂拥有InstiationAwareBeanPostProcessor
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			//遍历 工厂内的所有后处理器
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				//如果 bp 是 SmartInstantiationAwareBeanPostProcessor实例
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					//让exposedObject经过每个SmartInstantiationAwareBeanPostProcessor的包装
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		//返回最终经过层次包装后的对象
		return exposedObject;
	}

hasInstantiationAwareBeanPostProcessors()

返回此工厂是否拥有InstiationAwareBeanPostProcessor,它将在关闭时应用于单例bean

/**
	 * Indicates whether any InstantiationAwareBeanPostProcessors have been registered.
	 * <p>指示是否已经注册了任何 InstantiationAwareBeanPostProcessors 对象</p>
	 * */
	private volatile boolean hasInstantiationAwareBeanPostProcessors;
	
/**
	 * Return whether this factory holds a InstantiationAwareBeanPostProcessor
	 * that will get applied to singleton beans on shutdown.
	 * <p>返回此工厂是否拥有InstiationAwareBeanPostProcessor,它将在关闭时应用于单例bean</p>
	 * @see #addBeanPostProcessor
	 * @see org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
	 */
	protected boolean hasInstantiationAwareBeanPostProcessors() {
		return this.hasInstantiationAwareBeanPostProcessors;
	}

addSingletonFactory(beanName, singletonFactory)

如果需要,添加给定的单例对象工厂来构建指定的单例对象。

/**
	 * Cache of singleton objects: bean name to bean instance.
	 * <p>单例对象的高速缓存:beam名称-bean实例,所有bean对象最终都会放到对象中</p>
	 * */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/**
	 * Cache of singleton factories: bean name to ObjectFactory.
	 * <p>单例工厂的缓存:bean名称 - ObjectFactory </p>
	 * */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/**
	 * Cache of early singleton objects: bean name to bean instance.
	 * <p>早期单例对象的高速缓存:bean名称 - bean实例</p>
	 * <p>当从singletonFactories中获取到对应对象后,就会放到这个缓存中</p>
	 * */
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

	/**
	 * Set of registered singletons, containing the bean names in registration order.
	 * <p>已注册的单例集,按照注册顺序包含bean名称</p>
	 * <p>用于保证工厂内的beanName是唯一的</p>
	 * */
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

/**
	 * Add the given singleton factory for building the specified singleton
	 * if necessary.
	 * <p>如果需要,添加给定的单例对象工厂来构建指定的单例对象。</p>
	 * <p>To be called for eager registration of singletons, e.g. to be able to
	 * resolve circular references.
	 * <p>指定的单例对象。为单例的快速注册而调用,例如能够解决循环引用。</p>
	 * @param beanName the name of the bean -- bean 名
	 * @param singletonFactory the factory for the singleton object -- 单例对象工厂
	 */
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		//如果singleFactory为null,抛出异常
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		//使用singletonObjects进行加锁,保证线程安全
		synchronized (this.singletonObjects) {
			//如果 单例对象的高速缓存【beam名称-bean实例】 没有 beanName的对象
			if (!this.singletonObjects.containsKey(beanName)) {
				// 将beanName ,singletonFactory 放到 单例工厂的缓存【bean名称 - ObjectFactory】
				this.singletonFactories.put(beanName, singletonFactory);
				// 从 早期单例对象的高速缓存【bean名称 - bean实例】 移除 beanName的相关缓存对象
				this.earlySingletonObjects.remove(beanName);
				//将beanName 添加 已注册的单例集中
				this.registeredSingletons.add(beanName);
			}
		}
	}

populateBean(beanName, mbd, instanceWrapper);

用来自 BeanDefinition的属性值填充给定的BeanWrapper中的bean实例

Spring 5 AbstractAutowireCapableBeanFactory – populateBean源码解析(一)
Spring 5 AbstractAutowireCapableBeanFactory – populateBean源码解析(二)

initializeBean(beanName, exposedObject, mbd);

初始化给定的Bean实例,应用工厂回调以及init方法和BeanPostProcessors

Spring 5 AbstractAutowireCapableBeanFactory – initializeBean源码解析

getSingleton(beanName, false)

获取以beanName注册的(原始)单例对象:

Spring 5 DefaultSingletonBeanRegistry – getSingleton(String,ObjectFactory) 源码解析

hasDependentBean(beanName)

确定是否已经为给定名称注册了依赖Bean关系
具体代码由 DefaultSingleBeanRegistry 实现。

/**
	 * <p>存储 bean名到该bean名所要依赖的bean名 的Map,不理解的请看 {@link #registerDependentBean(String, String)}</p>
	 * Map between dependent bean names: bean name to Set of dependent bean names.
	 * <p>在相关的Bean名称之间映射:bean名称 - 一组相关的Bean名称</p>
	 * */
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
	
/**
	 * Determine whether a dependent bean has been registered for the given name.
	 * <p>确定是否已经为给定名称注册了依赖Bean关系</p>
	 * @param beanName the name of the bean to check -- 要检查的Bean名
	 */
	protected boolean hasDependentBean(String beanName) {
		return this.dependentBeanMap.containsKey(beanName);
	}

getDependentBeans(beanName);

如果有的话,返回依赖于指定Bean的所有Bean名称
具体代码由 DefaultSingleBeanRegistry 实现。

/**
	 * <p>存储 bean名到该bean名所要依赖的bean名 的Map,不理解的请看 {@link #registerDependentBean(String, String)}</p>
	 * Map between dependent bean names: bean name to Set of dependent bean names.
	 * <p>在相关的Bean名称之间映射:bean名称 - 一组相关的Bean名称</p>
	 * */
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
	
/**
	 * Return the names of all beans which depend on the specified bean, if any.
	 * <p>如果有的话,返回依赖于指定Bean的所有Bean名称</p>
	 * @param beanName the name of the bean
	 *                 -- bean名
	 * @return the array of dependent bean names, or an empty array if none
	 * 		-- 依赖Bean名称的数组,如果没有,则返回空数组
	 */
	public String[] getDependentBeans(String beanName) {
		//从dependentBeanMap中获取依赖Bean名称的数组
		Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
		//如果 dependentBeans 为null
		if (dependentBeans == null) {
			//返回数组
			return new String[0];
		}
		//使用 dependentBeanMap 进行加锁,以保证Set转数组时的线程安全
		synchronized (this.dependentBeanMap) {
			//将dependentBeans转换为数组
			return StringUtils.toStringArray(dependentBeans);
		}
	}

removeSingletonIfCreatedForTypeCheckOnly(dependentBean)

删除给定Bean名称的单例实例(如果有的话),但仅当它没有用于类型检查之外的其他目的时才删除.
具体代码由 AbstractBeanFactory 实现

/**
	 * Remove the singleton instance (if any) for the given bean name,
	 * but only if it hasn't been used for other purposes than type checking.
	 * <p>删除给定Bean名称的单例实例(如果有的话),但仅当它没有用于类型检查之外的其他目的时才删除</p>
	 * @param beanName the name of the bean
	 *                 -- bean名
	 * @return {@code true} if actually removed, {@code false} otherwise
	 * 		-- 如实际删除就为true;否则为false
	 */
	protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
		//如果已创建的bean名称中没有该beanName对应对象
		if (!this.alreadyCreated.contains(beanName)) {
			// 1.从该工厂单例缓存中删除具有给定名称的Bean。如果创建失败,则能够清理饿汉式注册 的单例
			// 2.FactoryBeanRegistrySupport重写以清除FactoryBean对象缓存
			// 3.AbstractAutowireCapableBeanFactory重写 以清除FactoryBean对象缓存
			removeSingleton(beanName);
			//有删除时返回true
			return true;
		}
		else {
			//没有删除时返回false
			return false;
		}
	}

registerDisposableBeanIfNecessary(beanName, bean, mbd);

将给定Bean添加到该工厂中的可丢弃Bean列表中,注册器可丢弃Bean接口 和/或 在工厂关闭 时调用给定销毁方法(如果适用)。只适用单例

Spring 5 AbstractBeanFactory – registerDisposableBeanIfNecessary 源码分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'deptServiceImpl': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'deptMapper' defined in file [D:\WorkSpace\work13\djd_server\target\classes\com\jiading\djd\mapper\DeptMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 40; 元素内容必须由格式正确的字符数据或标记组成。 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:893) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE] at com.jiading.djd.DjdApplication.main(DjdApplication.java:14) [classes/:na]报错了
最新发布
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值