温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Spring Bean怎么初始化

发布时间:2022-03-22 13:34:11 来源:亿速云 阅读:128 作者:小新 栏目:开发技术

这篇文章主要为大家展示了“Spring Bean怎么初始化”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Spring Bean怎么初始化”这篇文章吧。

前言

做Java都有很多年了,一直有一个疑惑: Spring 如何初始化bean,怎么调用反射实例化对象的,自己动手来解除这个疑惑。 过去我认为spring bean对象实例化一直都是由BeanPostProcessor接口实现类去做的,我就是不知道具体那个实现类。

三级缓存

为什么面试官特别喜欢问创建bean的三级缓存,主要是因为bean创建都是伴随着三级缓存之间的转换完成的,对象不同状态分别存在不同缓存中,下面我会在分析代码时,顺便支持对象如何在缓存中流转的。 先了解下spring 三级缓存。

    /** 一级缓存 用于存放完全可以使用单例bean,也就是初始化完成并且注入所有依赖 */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/** 二级缓存 过早暴露单例对象,此时bean刚刚完成初始化,未完成属性注入和执行 init 方法 */
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

	/** 三级缓存  装载创建bean的工厂对象 */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16)

三级缓存主要作用: 创建对象ObjectFactory首先放入三级换缓存中,当调用getObject 创建实例时,会将创建好对象加入二级缓存中,并且删除三级中缓存,当对象已经完成初始化方法和属性注入,再将缓存添加到一级缓存中,并且删除二级缓存。

doGetBean

从源头开始找,所有spring bean 初始化都是由AbstractBeanFactory.doGetBean方法实现的。下面我将源码减除臃肿部分,贴出来。

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
        //name 前缀处理  beanFactory beanName 带有&开头
		String beanName = transformedBeanName(name);
		Object beanInstance;
        //从三级缓存去取bean,三级中都没有则返回null,说明对象还没有创建
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) { //如果缓存中bean 是FactoryBean实例,要通过接口获取到实际bean
			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		else { 
             //判断bean对象标记是否正在创建中,如果正在创建中则不应该继续下去,出现依赖循环就会出现这个错误
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			BeanFactory parentBeanFactory = getParentBeanFactory();
            // 检查父容器是否存在,尝试从父容器中获取
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) { //缓存中标记beanName 正在被创建
				markBeanAsCreated(beanName);
			}
			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
					.tag("beanName", name);
			try {
				if (requiredType != null) {
					beanCreation.tag("beanType", requiredType::toString);
				}
				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) {  //bean 中@DependsOn 信息,用于标记bean之间初始化顺序,优先创建@DependsOn   中bean
					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);
						}
					}
				}

			     //创建单例对象
				if (mbd.isSingleton()) { //重点就在这里实例化对象  ,getSingleton 就是在这里将创建完成对象加入到一级缓存中
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) 
							destroySingleton(beanName);
							throw ex;
						}
					});
                    //如果生成bean 是FactoryBean ,再获取真正的对象
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
                //作用域 = prototype,因为不会放入缓存中,每次获取都要重新创建
				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);
					}
					beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else { // session request 这些作用域,由作用域容器去管理这些对象
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					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);
							}
						});
						beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new ScopeNotActiveException(beanName, scopeName, ex);
					}
				}
			}
			catch (BeansException ex) {
				beanCreation.tag("exception", ex.getClass().toString());
				beanCreation.tag("message", String.valueOf(ex.getMessage()));
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
			finally {
				beanCreation.end();
			}
		}
                //返回初始化成功的对象,一个对象初始化就这样完成的了  
		return adaptBeanInstance(name, beanInstance, requiredType);  
	}

大概总结一下上面代码流程:

  • 先从三级缓存中获取,如果缓存中都没有。再去判断是否存在父容器,从父容器中获取。没有正式进入bean 初始化流程,先根据beanName 获取到RootBeanDefinition,bean类元信息、先处理dependsOn中bean,保证bean依赖的创建顺序,下面会说明org.springframework.context.annotation.@DependsOn这个注解。下一步按照不同scope 进行bean 对象初始化。初始化流程就是这样,我们将目光放在单例bean 如何实例化,集中关注AbstractAutowireCapableBeanFactory.createBean 获取注册一个单例对象

@DependsOn 注解意思是实例化某个对象依赖于某一个实例化,但是不需要持有这个实例对象。比如bean A上 需要依赖bean b才能实例化,但是bean b 不需要作为他的属性,常常用于不同实例实例化顺序标记。

看下getSingleton方法

	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		synchronized (this.singletonObjects) {
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) { //标记bean 是否在销毁
					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!)");
				}
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
				}
				catch (BeanCreationException ex) {
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					addSingleton(beanName, singletonObject); //就是在这里删除二三级缓存,提交到一级缓存
				}
			}
			return singletonObject;
		}
	}
	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);
		}
	}

添加到一级缓存则说明bean已经完成实例化,可以正常使用了。下面看下如何进行实例化和属性注入的。

createBean

下面进入AbstractAutowireCapableBeanFactory.createBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		RootBeanDefinition mbdToUse = mbd;
        //克隆一份mbd => mbdToUse
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
                //通过BeanPostProcessors 增强返回一个代理对象,这个生成AOP的代理对象,使用多个BeanPostProcessors来处理
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
            // bean 对象实例化就这里实现
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

这里逻辑就比较简单了 ,克隆一份RootBeanDefinition用于初始化对象,resolveBeforeInstantiation 主要用于初始化代理对象情况,主要使用BeanPostProcessor子类InstantiationAwareBeanPostProcessor实现方法去实现对象初始化,并且在实例化成功后在调用后置方法进行对象依赖注入,这里可以看见此方法返回对象直接跳出方法栈,这里可以看出单例和代理对象还是有区别的。单例对象初始化就在doCreateBean 实现了

doCreateBean

下面就是AbstractAutowireCapableBeanFactory.doCreateBean非常接近对象如何实例化的了

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) { 
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);  //这个就是实例化方法
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// 使用BeanDefinitionPostProcessors 对合并bean进行实例化 
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// 这里就需要用到上面说的三级缓存知识了
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName)); //是否放入第三级缓存中
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); //将已经实例化的对象加入到第三级缓存 singletonFactories 
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper); //对属性进入注入,下面会具体分析的
			exposedObject = initializeBean(beanName, exposedObject, mbd); //执行初始化方法,或者注入Aware 接口bean
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		//下面代码省略
               //主要就是对设置了DisposableBean 接口销毁钩子方法处理
	}

这里代码主要分成三部分

  • 初始化实例,创建对象完成,并且添加到3级缓存。第3级缓存常常用于存储代理对象,因为有些类需要动态代理方法,需要生成代理对象,会委派给第三级缓存方法ObjectFactroy去实现的,普通对象如果不需要会直接返回。

  • 对实例化bean进行属性注入

  • 执行初始化方法,DisposableBean接口加入到disposableBeans容器中

instantiateBean

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {// 有实现Supplier 接口,由instanceSupplier.get() 方法创建实例
			return obtainFromSupplier(instanceSupplier, beanName);
		}

                //factoryName  使用工厂模式创建bean,调用工厂方法去创建,这个支持静态方法和factoryBean.invoke
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		boolean resolved = false;   //标记构造函数是否需要参数
		boolean autowireNecessary = false;  //标记构造方法的参数是否使用注入方式
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) { 
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
                               //使用构造函数注入方式实例化
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
                               //实例化对象
				return instantiateBean(beanName, mbd);
			}
		}

		// 获取构造函数参数
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		return instantiateBean(beanName, mbd);
	}

实例化方法instantiateBean最终会调用SimpleInstantiationStrategy.instantiate 进行实例化

instantiate

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		if (!bd.hasMethodOverrides()) {
			Constructor<?> constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							constructorToUse = clazz.getDeclaredConstructor(); //获取构造函数
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			return BeanUtils.instantiateClass(constructorToUse); //调用构造函数进行实例化
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

instantiateClass

	@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		if (!bd.hasMethodOverrides()) {
			Constructor<?> constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							constructorToUse = clazz.getDeclaredConstructor();
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			return BeanUtils.instantiateClass(constructorToUse);  //调用构造器进行初始化
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

这里要注意下先判断bean是否有方法重写的,没有则使用反射生成的构造器,有就使用gclib方式创建代理对象,具体实现方式就在org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate,有兴趣同学可以去学习下。 到此一个简单bean实例化完成了。

注入

下面进入IOC另一个特点,bean注入,先从AbstractAutowireCapableBeanFactory.populateBean方法开始

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
              //通过InstantiationAwareBeanPostProcessors.postProcessAfterInstantiation 如果返回true,目标实例内部的返回值会被populate,否则populate这个过程会被忽视
            //翻译说如果返回true可以执行字段注入 真的6666啊
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
                //获取注入方式分布有4种
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();  
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
            //依赖方式,模式都是没有类型检查,这种依赖方式一般都是xml 配置用得比较多,没有配置这里都是返回false
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); /

		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);  //获取注解标注需要注入方法或者是字段,并且进行注入
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}
		}
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

小知识点: AutowireCapableBeanFactory.AUTOWIRE_NO 表明不会对当前Bean进行外部类的注入,常规使用@Autowire、@Resource 都是这类型 剩下三种都是通过xml 或者 AutowireCapableBeanFactory.autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) 进行设置autowireMode 。

根据上面代码可以知道主流程bean注入都是由InstantiationAwareBeanPostProcessor 进行处理的,简单说明接口方法

方法描述
postProcessBeforeInitialization方法是最 先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走
postProcessAfterInitialization方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,postProcessPropertyValues就会被执行
postProcessPropertyValues对bean属性值赋值后调用,对属性值的修改。如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用。可以在该方法内对属性值进行修改
postProcessPropertiesBean属性赋值就是调用这个方法的

InstantiationAwareBeanPostProcessor 接口实现类主要分3个

  • ConfigurationClassPostProcessor:看类名就知道处理@Configuration实例化,并没有属性注入逻辑,不详讲略过。

  • CommonAnnotationBeanPostProcessor:这个类就是实现bean注入,但是是实现JSR-250 注解、@Resource,@EJB、@WebServiceRef,@WebServiceContext,@PostConstrusct、@PreDestory这些注解实现。

  • AutowiredAnnotationBeanPostProcessor:实现 @Autowired、@Value注入,并且支持JSR-330's @Inject,主要分析这个类就可以知道bean 注入的。

AutowiredAnnotationBeanPostProcessor分析

	private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
	@SuppressWarnings("unchecked")
	public AutowiredAnnotationBeanPostProcessor() {
		this.autowiredAnnotationTypes.add(Autowired.class);
		this.autowiredAnnotationTypes.add(Value.class);
		try {
			this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
					ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
			logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

在初始化时就将支持注解加入集合中,再使用扫描器去扫描方法、构造器、字段,如果有这些注解就进行注入。

看下怎么判断是否需要注入的

	@Nullable
	private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
		MergedAnnotations annotations = MergedAnnotations.from(ao);
		for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
			MergedAnnotation<?> annotation = annotations.get(type);
			if (annotation.isPresent()) {
				return annotation;
			}
		}
		return null;
	}

AccessibleObject 是Method、Field、Constructor 父类。

postProcessProperties 如何实现bean注入的

	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
              //获取需要注入字段,方法
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs); //注入
		}
		catch (BeanCreationException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
		}
		return pvs;
	}
       //下面就行获取InjectionMetadata 
	private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
		// Fall back to class name as cache key, for backwards compatibility with custom callers.
		String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
		// 快速从缓存中获取,如果没有加锁去解析,然后在结果放入缓存中
		InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
		if (InjectionMetadata.needsRefresh(metadata, clazz)) { 
			synchronized (this.injectionMetadataCache) { //双重检查
				metadata = this.injectionMetadataCache.get(cacheKey);
				if (InjectionMetadata.needsRefresh(metadata, clazz)) {
					if (metadata != null) {
						metadata.clear(pvs);
					}
					metadata = buildAutowiringMetadata(clazz); 
					this.injectionMetadataCache.put(cacheKey, metadata); 
				}
			}
		}
		return metadata;
	}
  • InjectionMetadata 主要是集合bean需要被注入类型,因为已经解析过bean Class信息了,相当于解析结果装起来

看下如何去扫描方法、字段的

 	private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
       //从给定注解中判断class 是否携带这个注解
		if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) { 
			return InjectionMetadata.EMPTY;
		}

		List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
            //遍历所有Field,找出扫描的注解,特意标注不支持static 修饰field 
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				MergedAnnotation<?> ann = findAutowiredAnnotation(field);
				if (ann != null) {
					if (Modifier.isStatic(field.getModifiers())) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation is not supported on static fields: " + field);
						}
						return;
					}
                     // 获取注解内 required 值
					boolean required = determineRequiredStatus(ann);
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                //获取方法上桥接方法,因为泛型类型擦除,要对桥接方法进行安全检查,防止在调用是出现异常
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
					return;
				}
                //获取注解
				MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
               //方法安全检查
				if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
					if (Modifier.isStatic(method.getModifiers())) { //不支持静态方法注入
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation is not supported on static methods: " + method);
						}
						return;
					}
					if (method.getParameterCount() == 0) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation should only be used on methods with parameters: " +
									method);
						}
					}
					boolean required = determineRequiredStatus(ann);
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
					currElements.add(new AutowiredMethodElement(method, required, pd));
				}
			});
           // 这样写是为了后面加入排在队列前面,父类属性优先于子类
			elements.addAll(0, currElements);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class); //这里写得很好,向上解析父类,直到是Object 为止

		return InjectionMetadata.forElements(elements, clazz);
	}

逻辑非常简单,就是根据给定注解去class获取指定的注解,从而获取到需要注入类型,但是几行简单的代码可以看出强大编码能力,学习了????。 现在需要注入对象已经获取到,看如何注入吧

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
		Collection<InjectedElement> checkedElements = this.checkedElements;
		Collection<InjectedElement> elementsToIterate =
				(checkedElements != null ? checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
			for (InjectedElement element : elementsToIterate) {
				element.inject(target, beanName, pvs);
			}
		}
	}

		@Override
		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			Field field = (Field) this.member;
			Object value;
			if (this.cached) {
				try {
					value = resolvedCachedArgument(beanName, this.cachedFieldValue);
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Unexpected removal of target bean for cached argument -> re-resolve
					value = resolveFieldValue(field, bean, beanName);
				}
			}
			else {
				value = resolveFieldValue(field, bean, beanName);
			}
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		}

		private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
			DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
			desc.setContainingClass(bean.getClass());
			Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
			Assert.state(beanFactory != null, "No BeanFactory available");
			TypeConverter typeConverter = beanFactory.getTypeConverter(); //类型转换器
			Object value;
			try {
				value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
			}
			synchronized (this) {
				if (!this.cached) {
					Object cachedFieldValue = null;
					if (value != null || this.required) {
						cachedFieldValue = desc;
                        // 将注入关系添加到容器中,方便bean销毁时同步销毁
						registerDependentBeans(beanName, autowiredBeanNames);
						if (autowiredBeanNames.size() == 1) {
							String autowiredBeanName = autowiredBeanNames.iterator().next();
							if (beanFactory.containsBean(autowiredBeanName) &&
									beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { //这些都是为了缓存起来
								cachedFieldValue = new ShortcutDependencyDescriptor(
										desc, autowiredBeanName, field.getType());
							}
						}
					}
					this.cachedFieldValue = cachedFieldValue;
					this.cached = true;
				}
			}
			return value;
		}
	}

主要核心是如从缓存获取到需要注入类型实例在beanFactory.resolveDependency中 进入DefaultListableBeanFactory看下

	public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
		if (Optional.class == descriptor.getDependencyType()) {
			return createOptionalDependency(descriptor, requestingBeanName);
		}
		else if (ObjectFactory.class == descriptor.getDependencyType() ||
				ObjectProvider.class == descriptor.getDependencyType()) {
			return new DependencyObjectProvider(descriptor, requestingBeanName);
		}
		else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
			return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
		}
		else {
                        //懒加载  扫描@Lazy注解,返回一个代理对象
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

@Lazy 使用注解修饰bean 或者Class,在容器初始化化时不会立刻创建,只要需要使用bean才会创建的。 根据类型Optional、ObjectFactory、Provider,还有懒加载情景不同的处理,这些处理本质都是要调用doResolveDependency方法初始化对象,无论那种对象都要 获取原始对象然后再交给这些接口去包装增强。

	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
            //如果这个注入是通过构造器注入,可以从构造器解析缓存中去获取注入信息点    
		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}

			Class<?> type = descriptor.getDependencyType();
                     //尝试从注解中获取默认值   @Value  的value  
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
				if (value instanceof String) {
					String strVal = resolveEmbeddedValue((String) value);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
					return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
				}
				catch (UnsupportedOperationException ex) {
					// A custom TypeConverter which does not support TypeDescriptor resolution...
					return (descriptor.getField() != null ?
							converter.convertIfNecessary(value, type, descriptor.getField()) :
							converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
				}
			}
              //多种混合类型处理,stream、collection、Map Array 这些
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}

                  //根据类型获取容器中bean名,返回map key就是bean名,value 初始从容器中获取对象,如果没有找到就会抛出异常了
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;

			if (matchingBeans.size() > 1) {  //出现一个类型,不同实例,可以根据@Primary, @Priority、属性名方式去配置
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {  //没有确定,抛出异常
						return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
					}
					else {
						return null;
					}
				}
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				// We have exactly one match.
				Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}

			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(autowiredBeanName);
			}
			if (instanceCandidate instanceof Class) {  //这里其实就是从容器中获取实例,如果这时候没有初始化,就走上面初始化流程
				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
			}
			Object result = instanceCandidate;
			if (result instanceof NullBean) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				result = null;
			}
			if (!ClassUtils.isAssignableValue(type, result)) {
				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
			}
			return result;
		}
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}

这个方法简单做个总结,先是处理 @Value 情况,然后通过findAutowireCandidates 通过类型去容器中获取实例,如何实例还没有初始化,就会调用上面那个初始化过程,将初始化对象返回。根据注入类型进行相应处理,像stream、Collection,这些混合类型都是直接添加进去。如果出现了一个类型多个bean情况,这时就是就是@Primary、@Priority这些注解来判断或者根据属性名去和beanName匹配,最后将bean对象返回。 这里就简单看完一个bean初始化流程了。

以上是“Spring Bean怎么初始化”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI