【spring源码系列】之【Bean的实例化】

123 阅读11分钟

目录

  1. Bean的实例化
  2. 流程概览
  3. 源码分析 3.1 createBeanInstance概览 3.1 使用Supplier接口 3.2 使用FactoryMethod方法实例化 3.3 有参构造函数实例化 3.4 无参构造函数实例化 3.5 bean实例化后的收尾工作
  4. 案例 4.1 使用工厂方法创建bean 4.2 带有autowired的有参构造函数 4.3 不带有autowired的有参构造函数 4.4 无参构造函数
  5. 总结 image.png

人生需要探索的热情、坚持的勇气以及热爱生活热爱自己的力量。

1. Bean的实例化

上一篇讲述了bean的生命周期,其中第一步就涉及到了bean的实例化,本文重点分析bean实例化,先进入源码中的AbstractAutowireCapableBeanFactory类中的createBeanInstance方法。

2. 流程概览

image

上述图描述了bean的实例化过程中的主要步骤:

  1. 如果存在 Supplier 回调,则调用 obtainFromSupplier() 进行初始化;
  2. 如果存在工厂方法,则使用工厂方法进行初始化;
  3. 如果构造函数参数不为空,则先获取autowired注解的构造函数,再获取构造函数里面的参数,参数是引用类型的话,再次循环调用容器去获取,最后通过反射完成实例化;
  4. 如果构造函数无参,则使用默认无参构造函数实例化;
  5. 最后将bean添加到一级缓存,并清除二级三级缓存里的bean。

3. 源码分析

3.1 createBeanInstance概览

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();
		// 使用Supplier接口获取
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		// 使用FactoryMethod方法实例化
		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);
			}
		}

		// Candidate constructors for autowiring?
		// 构造函数有参autowired修饰
		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);
}

3.1 使用Supplier接口

Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		// 使用Supplier接口获取
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

进入obtainFromSupplier方法

protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
		Object instance;

		String outerBean = this.currentlyCreatedBean.get();
		this.currentlyCreatedBean.set(beanName);
		try {
                        // 从instanceSupplier获取
			instance = instanceSupplier.get();
		}
		finally {
			if (outerBean != null) {
				this.currentlyCreatedBean.set(outerBean);
			}
			else {
				this.currentlyCreatedBean.remove();
			}
		}

		if (instance == null) {
			instance = new NullBean();
		}
                // 包装成BeanWrapper
		BeanWrapper bw = new BeanWrapperImpl(instance);
                // 初始化BeanWrapper
		initBeanWrapper(bw);
		return bw;
	}

上述源码显示从从instanceSupplier获取,而instanceSupplier是一个函数式接口:

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}
那在何时对该instanceSupplier进行设置的呢?不妨来看一下RootBeanDefinition:

protected BeanWrapper instantiateUsingFactoryMethod(
	String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

	return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

由此可见,在初始化BeanDefinition的时候,就已经将instanceSupplier设置, 随后从instanceSupplier.get()获取,最后包装成BeanWrapper对象后,对其初始化。

3.2 使用FactoryMethod方法实例化 如果工厂方法不为空,则使用工厂方法实例化:

// 使用FactoryMethod方法实例化
if (mbd.getFactoryMethodName() != null) {
    return instantiateUsingFactoryMethod(beanName, mbd, args);
}
下面进入instantiateUsingFactoryMethod方法:

protected BeanWrapper instantiateUsingFactoryMethod(
			String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

    return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

先创建一个ConstructorResolver对象,然后调用其instantiateUsingFactoryMethod方法,该方法细节很多,看如下主要步骤:

	public BeanWrapper instantiateUsingFactoryMethod(
			String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);

		Object factoryBean;
		Class<?> factoryClass;
		boolean isStatic;
		// 获取工厂bean
		String factoryBeanName = mbd.getFactoryBeanName();
		// RootBeanDefinition的factory-bean属性不为空
		if (factoryBeanName != null) {
			if (factoryBeanName.equals(beanName)) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"factory-bean reference points back to the same bean definition");
			}
			factoryBean = this.beanFactory.getBean(factoryBeanName);
			if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
				throw new ImplicitlyAppearedSingletonException();
			}
			factoryClass = factoryBean.getClass();
			isStatic = false;
		}
		// RootBeanDefinition的factory-bean属性为空,需要静态方法初始化
		else {
			// It's a static factory method on the bean class.
			if (!mbd.hasBeanClass()) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"bean definition declares neither a bean class nor a factory-bean reference");
			}
			factoryBean = null;
			factoryClass = mbd.getBeanClass();
			isStatic = true;
		}
		// 工厂方法与参数
		Method factoryMethodToUse = null;
		ArgumentsHolder argsHolderToUse = null;
		Object[] argsToUse = null;

		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			// 首先尝试从缓存中获取参数
			Object[] argsToResolve = null;
			synchronized (mbd.constructorArgumentLock) {
				factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
				if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
					// Found a cached factory method...
					argsToUse = mbd.resolvedConstructorArguments;
					if (argsToUse == null) {
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			if (argsToResolve != null) {
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
			}
		}

		if (factoryMethodToUse == null || argsToUse == null) {
			// Need to determine the factory method...
			// Try all methods with this name to see if they match the given arguments.
			// 获取工厂类全名
			factoryClass = ClassUtils.getUserClass(factoryClass);

			List<Method> candidates = null;
			if (mbd.isFactoryMethodUnique) {
				if (factoryMethodToUse == null) {
					factoryMethodToUse = mbd.getResolvedFactoryMethod();
				}
				if (factoryMethodToUse != null) {
					candidates = Collections.singletonList(factoryMethodToUse);
				}
			}
			if (candidates == null) {
				candidates = new ArrayList<>();
				Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
				for (Method candidate : rawCandidates) {
					// 如果有static 且为工厂方法,则添加到 candidates 中
					if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
						candidates.add(candidate);
					}
				}
			}

			// 工厂类只有一个工厂方法
			if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
				Method uniqueCandidate = candidates.get(0);
				if (uniqueCandidate.getParameterCount() == 0) {
					mbd.factoryMethodToIntrospect = uniqueCandidate;
					synchronized (mbd.constructorArgumentLock) {
						mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
						mbd.constructorArgumentsResolved = true;
						mbd.resolvedConstructorArguments = EMPTY_ARGS;
					}
                                        // 初始化bean
					bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
					return bw;
				}
			}

			// 工厂类有多个工厂方法,按照参数数量降序排列
			if (candidates.size() > 1) {  // explicitly skip immutable singletonList
				candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
			}

			ConstructorArgumentValues resolvedValues = null;
			boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
			int minTypeDiffWeight = Integer.MAX_VALUE;
			Set<Method> ambiguousFactoryMethods = null;

			int minNrOfArgs;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				// We don't have arguments passed in programmatically, so we need to resolve the
				// arguments specified in the constructor arguments held in the bean definition.
				if (mbd.hasConstructorArgumentValues()) {
					ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
					resolvedValues = new ConstructorArgumentValues();
					minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
				}
				else {
					minNrOfArgs = 0;
				}
			}

			LinkedList<UnsatisfiedDependencyException> causes = null;
			// 遍历工厂方法
			for (Method candidate : candidates) {
				int parameterCount = candidate.getParameterCount();

				if (parameterCount >= minNrOfArgs) {
					ArgumentsHolder argsHolder;

					Class<?>[] paramTypes = candidate.getParameterTypes();
					if (explicitArgs != null) {
						// Explicit arguments given -> arguments length must match exactly.
						if (paramTypes.length != explicitArgs.length) {
							continue;
						}
						argsHolder = new ArgumentsHolder(explicitArgs);
					}
					else {
						// Resolved constructor arguments: type conversion and/or autowiring necessary.
						try {
							String[] paramNames = null;
							ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
							if (pnd != null) {
								paramNames = pnd.getParameterNames(candidate);
							}
							argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
									paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
						}
						catch (UnsatisfiedDependencyException ex) {
							if (logger.isTraceEnabled()) {
								logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
							}
							// Swallow and try next overloaded factory method.
							if (causes == null) {
								causes = new LinkedList<>();
							}
							causes.add(ex);
							continue;
						}
					}

					int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
							argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
					// Choose this factory method if it represents the closest match.
					if (typeDiffWeight < minTypeDiffWeight) {
						factoryMethodToUse = candidate;
						argsHolderToUse = argsHolder;
						argsToUse = argsHolder.arguments;
						minTypeDiffWeight = typeDiffWeight;
						ambiguousFactoryMethods = null;
					}
					// Find out about ambiguity: In case of the same type difference weight
					// for methods with the same number of parameters, collect such candidates
					// and eventually raise an ambiguity exception.
					// However, only perform that check in non-lenient constructor resolution mode,
					// and explicitly ignore overridden methods (with the same parameter signature).
					else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
							!mbd.isLenientConstructorResolution() &&
							paramTypes.length == factoryMethodToUse.getParameterCount() &&
							!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
						if (ambiguousFactoryMethods == null) {
							ambiguousFactoryMethods = new LinkedHashSet<>();
							ambiguousFactoryMethods.add(factoryMethodToUse);
						}
						ambiguousFactoryMethods.add(candidate);
					}
				}
			}

			if (factoryMethodToUse == null || argsToUse == null) {
				if (causes != null) {
					UnsatisfiedDependencyException ex = causes.removeLast();
					for (Exception cause : causes) {
						this.beanFactory.onSuppressedException(cause);
					}
					throw ex;
				}
				List<String> argTypes = new ArrayList<>(minNrOfArgs);
				if (explicitArgs != null) {
					for (Object arg : explicitArgs) {
						argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
					}
				}
				else if (resolvedValues != null) {
					Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
					valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
					valueHolders.addAll(resolvedValues.getGenericArgumentValues());
					for (ValueHolder value : valueHolders) {
						String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
								(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
						argTypes.add(argType);
					}
				}
				String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"No matching factory method found: " +
						(mbd.getFactoryBeanName() != null ?
							"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
						"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
						"Check that a method with the specified name " +
						(minNrOfArgs > 0 ? "and arguments " : "") +
						"exists and that it is " +
						(isStatic ? "static" : "non-static") + ".");
			}
			else if (void.class == factoryMethodToUse.getReturnType()) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Invalid factory method '" + mbd.getFactoryMethodName() +
						"': needs to have a non-void return type!");
			}
			else if (ambiguousFactoryMethods != null) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Ambiguous factory method matches found in bean '" + beanName + "' " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
						ambiguousFactoryMethods);
			}

			if (explicitArgs == null && argsHolderToUse != null) {
				mbd.factoryMethodToIntrospect = factoryMethodToUse;
				argsHolderToUse.storeCache(mbd, factoryMethodToUse);
			}
		}
                // 初始化bean
		bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
		return bw;
	}

这个方法体太多if条件,通过拆解主要流程可以归纳为以下步骤: step1:获取工厂bean的名字; step2:判断工厂bean名字是否为空,如果不为空,从容器中获取工厂bean,并将非静态方法设为false; step3:如果工厂bean的名字为空,则使用静态方法实例化。 上述其他代码都是初始化前工厂方法的遍历,工厂方法的排序、以及参数的获取,最终再调用instantiate方法完成初始化;而instantiate的核心代码就一句话

return this.beanFactory.getInstantiationStrategy().instantiate(
						mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);
getInstantiationStrategy()获取实例化的策略,这里是使用工厂方法来实例化bean,进入instantiate方法:

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			@Nullable Object factoryBean, final Method factoryMethod, Object... args) {

		try {
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					ReflectionUtils.makeAccessible(factoryMethod);
					return null;
				});
			}
			else {
				ReflectionUtils.makeAccessible(factoryMethod);
			}

			Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
			try {
				currentlyInvokedFactoryMethod.set(factoryMethod);
                                // 核心代码就是通过反射完成实例化
				Object result = factoryMethod.invoke(factoryBean, args);
...

最终是通过反射完成bean的实例化。

3.3 有参构造函数实例化
如果没有通过工厂方法完成实例化,那么继续往下走如下代码:
            // 寻找实例化的bean中有@Autowired注解的构造函数
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
		// 如果ctors不为空,就说明构造函数中有@Autowired注解
		return autowireConstructor(beanName, mbd, ctors, args);
	}
有参构造函数的实例化过程,通过determineConstructorsFromBeanPostProcessors这个方法完成,同时也是BeanPostProcessor接口类的应用,最终会调到 AutowiredAnnotationBeanPostProcessor类的方法,在方法中会扫描有注解的构造函数然后完成装配过程。然后把有@Autowired 注解的构造函数返回。

上面已经拿到了构造函数,autowireConstructor就是获取参数的过程,其方法比较复杂,跟之前的instantiateUsingFactoryMethod类似,不再细究,把主要核心代码拿出来分析:

// 获取构造函数参数的值
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
createArgumentArray方法,获取构造函数参数的值,进入方法,找到核心代码:

// 解析所有构造函数的参数值
Object autowiredArgument = resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, converter, fallback);
resolveAutowiredArgument方法解析构造函数参数的值,再进入:

// 解析依赖
return this.beanFactory.resolveDependency(new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);

再次进入:

// 执行解析依赖
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
// 解析candidate
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
beanFactory.getBean(beanName)
最终会感觉眼前一亮,通过非常熟悉的getBean获取实例,然后会走到普通情况下的getBean方法,通过上面得到一个结论,不管是 Field、Method、还是构造函数中有@Autowired 注解引入的类,都是通过getBean方法进行实例化获取bean的实例的。

3.4 无参构造函数实例化 无参构造函数的实例化过程 instantiateBean(beanName, mbd)这就是简单的反射实例化。大部分类的实例化都会走这个逻辑。进入实现类的方法:

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.
                        // 创建cglib子类后在实例化
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

3.5 bean实例化后的收尾工作 当创建完后,回到上一篇讲的getSingleton方法:

// 创建bean实例
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

再来回顾一下该方法:

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 (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 + "'");
				}
				// bean单例创建前
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					// 调用createBean方法创建bean
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					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;
					}
					// 创建完成后要从正在实例化的bean集合singletonsCurrentlyInCreation中删除该bean
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					// bean加入缓存
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

以及addSingleton相关代码如下:

	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			// 一级缓存存放bean
			this.singletonObjects.put(beanName, singletonObject);
			// 三级缓存移除bean
			this.singletonFactories.remove(beanName);
			// 二级缓存移除bean
			this.earlySingletonObjects.remove(beanName);
			//
			this.registeredSingletons.add(beanName);
		}
	}

可以看出getSingleton方法总共做了如下几件事:

bean创建前,将正在创建的bean放入singletonsCurrentlyInCreation集合; bean创建过程中,就是上一篇写的bean的创建整个过程,本篇只是涉及建实例这一个环节; bean创建后,从集合singletonsCurrentlyInCreation中移除正在创建的bean; bean加入一级缓存,同时移除三级缓存与二级缓存中的bean。 4. 案例 4.1 使用工厂方法创建bean 使用如下配置文件spring.xml,第一种是使用factory-bean属性,bean后面不带class属性;第二种是bean使用class属性,factory-method属性后面是静态工厂方法:

        <context:component-scan base-package="com.wzj"/>
	<bean id="factoryMethodbean" class="com.wzj.bean.FactoryMethodBean"/>
	<bean id="wzj" factory-bean="factoryMethodbean" factory-method="factoryMethod"/>

	<bean id="wzj2"  class="com.wzj.bean.Wzj" factory-method="factoryMethod"/>
FactoryMethodBean类如下,

public class FactoryMethodBean {

    public Object factoryMethod() {
        return new Wzj();
    }


    public Object factoryMethod(SC sc, CQ cq) {
        return new Wzj(sc,cq);
    }

}

实例化类如下:

public class Wzj {
    public static Wzj factoryMethod() {
        return new Wzj();
    }

    SC sc;

    public Wzj() {

    }

    public Wzj(SC sc, CQ cq) {
        this.sc = sc;
        this.cq = cq;
    }

    CQ cq;

}
依赖的属性值分别代表四川、重庆,实现了Province接口:

@Component
public class CQ implements Province{

    private static String flag = "CQ";

    @Override
    public boolean support(String flag) {
        return CQ.flag.equalsIgnoreCase(flag);
    }

    @Override
    public String handler() {
        System.out.println("======CQ处理类处理");
        return null;
    }
}
@Component
public class SC implements Province{

    private static String flag = "SC";

    @Override
    public boolean support(String flag) {
        return SC.flag.equalsIgnoreCase(flag);
    }

    @Override
    public String handler() {
        System.out.println("======SC处理类处理");
        return null;
    }
}
public interface Province {

    public boolean support(String flag);

    public String handler();
}

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring.xml"})
public class TestSpring {
    @Test
    public void testCreateBeanInstance() {
        ClassPathXmlApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring.xml");
        Wzj wzj = (Wzj) applicationContext.getBean("wzj");
        Wzj wzj2 = (Wzj) applicationContext.getBean("wzj2");
        System.out.println(wzj.getClass().getName());
        System.out.println(wzj2.getClass().getName());
    }

最后结果:

com.wzj.bean.Wzj
com.wzj.bean.Wzj

4.2 带有autowired的有参构造函数 测试示例代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring.xml"})
public class TestSpring {
    @Test
    public void testCreateBeanInstance() {
        ClassPathXmlApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring.xml");
        AutowiredConstructorBean fmc = (AutowiredConstructorBean)applicationContext.getBean("autowiredConstructorBean");
        System.out.println(fmc.getClass().getName());
    }
实例化AutowiredConstructorBean的代码:

@Component
public class AutowiredConstructorBean {

    @Autowired
    private SC sc;

    @Resource
    private CQ cq;

    @Autowired
    public AutowiredConstructorBean(SC sc,CQ cq) {
        System.out.println(sc);
        System.out.println(cq);
    }
}

结果会打印如下:

com.wzj.bean.AutowiredConstructorBean
如果再加一个带@Autowired参数的构造函数:

@Component
public class AutowiredConstructorBean {

    @Autowired
    private SC sc;

    @Resource
    private CQ cq;

    @Autowired
    public AutowiredConstructorBean(SC sc,CQ cq) {
        System.out.println(sc);
        System.out.println(cq);
    }

    @Autowired(required = false)
    public AutowiredConstructorBean(SC sc) {
        System.out.println(sc);
    }
}

结果就会报错:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'autowiredConstructorBean': Invalid autowire-marked constructor: public com.wzj.bean.AutowiredConstructorBean(com.wzj.strategy.SC). Found constructor with 'required' Autowired annotation already: public com.wzj.bean.AutowiredConstructorBean(com.wzj.strategy.SC,com.wzj.strategy.CQ)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:339)

通过调试,发现报错的根源是在第二次拿构造函数的参数时,执行了AutowiredAnnotationBeanPostProcessor中determineCandidateConstructors方法的如下代码:

						if (ann != null) {
							if (requiredConstructor != null) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructor: " + candidate +
										". Found constructor with 'required' Autowired annotation already: " +
										requiredConstructor);
							}

提示已经有required修饰的构造函数存在,解决上述问题,如果有两个@Autowired注解的有参构造函数,需要将两个构造函数@Autowired都加上required = false)。只不过构造函数会根据参数个数的多少降序排序,参数多的构造函数会优先执行,后面的那个构造函数不会被执行。

4.3 不带有autowired的有参构造函数

public class AutowiredConstructorBean {
    public AutowiredConstructorBean(SC sc,CQ cq) {
        System.out.println(sc);
        System.out.println(cq);
    }
}

最后也能完成初始化。

4.4 无参构造函数

public class AutowiredConstructorBean {
    
}

通过上面测试案例最后也能完成实例化。

  1. 总结 本篇讲述了bean实例化的多种方式,可以学到spring为用户提供多种创建方式,从而看出spring创建bean方式的灵活性,在我们写代码时候,也可以考虑多种策略,来完成某种功能,提高可扩展性与灵活性。