Spring源码学习06

1.createInstance方法,Spring给我们提供了三种创建bean实例的方式,1.工厂方法2.有参构造器,3.无参构造器

逻辑很简单

a.首先判断工厂方法是否存在,如果有则使用工厂方法实例化bean

b.判断程序有没有传自定义参数获取bean如果没有判断有没有解析过构造函数,如果有的话,判断是否为构造函数解析过参数

如果没有解析过则认为,人家用的是默认构造器即无参的直接简单实例化bean,否则需要使用autowireConstrucotr方法去创建bean

c.程序往下执行会判断当前bean是否有构造参数/bean中定义是否用autwireConstructor或者bean定义包含构造参数函数或者自定义传参不为null都需要使用autowireConstructor创建bean

d.使用无参构造初始化bean

2.instantiateUsingFactoryMethod(autowireConstructor),即使用工厂方法初始化bean将bean的初始化委托给了ConstructorResolver的instantiateUsingFactoryMethod方法,使用构造器创建对象的方法委托给了autowireConstructor,

public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
			Constructor<?>[] chosenCtors, final Object[] explicitArgs) {

		BeanWrapperImpl bw = new BeanWrapperImpl();
		//使用在此工厂注册的自定义编辑器初始化给定的BeanWrapper。 为将要创建和填充bean实例的BeanWrappers调用
		//初始化bean创建和填充bean所需要使用的propertyEditors
		this.beanFactory.initBeanWrapper(bw);
		//要使用的构造函数
		Constructor<?> constructorToUse = null;
		//持有参数
		ArgumentsHolder argsHolderToUse = null;
		//待使用的参数
		Object[] argsToUse = null;
		//如果用户传入了指定参数
		if (explicitArgs != null) {
			//直接赋值
			argsToUse = explicitArgs;
		}
		else {
			//从配置文件中解析
			Object[] argsToResolve = null;
			//看看是否已经解析过了
			synchronized (mbd.constructorArgumentLock) {
				//已经解析过的构造参数
				constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
				//已经解析过了参数
				if (constructorToUse != null && mbd.constructorArgumentsResolved) {
					// 直接获取
					argsToUse = mbd.resolvedConstructorArguments;
					//还没有解析到
					if (argsToUse == null) {
						//使用配置的构造参数后面会解析
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			//配置的构造参数不为null,譬如构造函数要求使用int,但是我们原始参数值可能是String类型"1"
			if (argsToResolve != null) {
				//解析配置的构造参数为匹配构造器的参数
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
			}
		}
		//构造器还未解析,这种情况就是没有从缓存取到可用的构造器了嘿嘿
		if (constructorToUse == null) {
			// Need to resolve the constructor.
			//判断是否需要构造器注入
			boolean autowiring = (chosenCtors != null ||
					mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
			ConstructorArgumentValues resolvedValues = null;
			//参数的最小长度
			int minNrOfArgs;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				//构造器参数变量保存
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				//承载解析后的构造函数参数值
				resolvedValues = new ConstructorArgumentValues();
				//
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}

			// Take specified constructors, if any.
			//指定的构造函数数组
			Constructor<?>[] candidates = chosenCtors;
			//没有的话通过反射获取所有的构造函数
			if (candidates == null) {
				//beanClass
				Class<?> beanClass = mbd.getBeanClass();
				try {

					candidates = (mbd.isNonPublicAccessAllowed() ?
							beanClass.getDeclaredConstructors() : beanClass.getConstructors());
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
			}
			//排序现有的构造函数,首先是构造函数的访问性public的参数数量降序,然后非public的按照参数数量排序
			AutowireUtils.sortConstructors(candidates);

			int minTypeDiffWeight = Integer.MAX_VALUE;
			//保存相似的构造器
			Set<Constructor<?>> ambiguousConstructors = null;
			LinkedList<UnsatisfiedDependencyException> causes = null;
			//遍历所有构造函数
			for (Constructor<?> candidate : candidates) {
				//构造函数对应的参数类型
				Class<?>[] paramTypes = candidate.getParameterTypes();

				if (constructorToUse != null && argsToUse.length > paramTypes.length) {
					// Already found greedy constructor that can be satisfied ->
					// do not look any further, there are only less greedy constructors left.
					break;
				}
				//构造函数参数长度不够,继续循环
				if (paramTypes.length < minNrOfArgs) {
					continue;
				}
				//组装该构造函数所需要的参数
				ArgumentsHolder argsHolder;
				if (resolvedValues != null) {
					try {
						//获取ConstructorProperties注释上的paramNames
						String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
						if (paramNames == null) {
							//名称探索器
							ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
							if (pnd != null) {
								//解析构造函数上的参数名称
								paramNames = pnd.getParameterNames(candidate);
							}
						}
						argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
								getUserDeclaredConstructor(candidate), autowiring);
					}
					catch (UnsatisfiedDependencyException ex) {
						if (this.beanFactory.logger.isTraceEnabled()) {
							this.beanFactory.logger.trace(
									"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
						}
						// Swallow and try next constructor.
						if (causes == null) {
							causes = new LinkedList<UnsatisfiedDependencyException>();
						}
						causes.add(ex);
						continue;
					}
				}
				else {
					//如果构造器的长度和给定参数长度不一致直接进入下一轮循环
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					//创建ArgumentsHolder
					argsHolder = new ArgumentsHolder(explicitArgs);
				}
				//
				int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
						argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
				// 如果它代表最接近的匹配,请选择此构造函数
				if (typeDiffWeight < minTypeDiffWeight) {
					constructorToUse = candidate;
					argsHolderToUse = argsHolder;
					argsToUse = argsHolder.arguments;
					minTypeDiffWeight = typeDiffWeight;
					ambiguousConstructors = null;
				}
				else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
					if (ambiguousConstructors == null) {
						ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
						ambiguousConstructors.add(constructorToUse);
					}
					ambiguousConstructors.add(candidate);
				}
			}
			//解析结束后待使用构造参数还未Null,将异常抛出
			if (constructorToUse == null) {
				if (causes != null) {
					UnsatisfiedDependencyException ex = causes.removeLast();
					for (Exception cause : causes) {
						this.beanFactory.onSuppressedException(cause);
					}
					throw ex;
				}
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Could not resolve matching constructor " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
			}
			//如果不以宽松模式解析并且相似的构造函数存在,抛出异常,给出hint提示
			else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Ambiguous constructor matches found in bean '" + beanName + "' " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
						ambiguousConstructors);
			}
			//缓存已经解析的构造函数
			if (explicitArgs == null) {
				argsHolderToUse.storeCache(mbd, constructorToUse);
			}
		}

		try {
			Object beanInstance;

			if (System.getSecurityManager() != null) {
				final Constructor<?> ctorToUse = constructorToUse;
				final Object[] argumentsToUse = argsToUse;
				beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
					@Override
					public Object run() {
						return beanFactory.getInstantiationStrategy().instantiate(
								mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
					}
				}, beanFactory.getAccessControlContext());
			}
			else {
				//实例化Bean
				beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
						mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
			}

			bw.setBeanInstance(beanInstance);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean instantiation via constructor failed", ex);
		}
	}

个人认为解析的过程和保存的缓存过程理解下就好了,没必要深究,上述方法我们比较在意的地方是bean的实例化,如果是我自己开发这种ioc容器肯定会直接使用反射创建了,但是Spring没有这么做

 这是因为我们可以在bean中配置lookup-method和replacemethod,spring需要判断bean defition属性中是否存在,如果存在则需要生成代理对象

 对于instantiateWithMethodInjection方法我们现在就不进行深入了。

3.我们回到doCreateBean方法在创建bean成功后,Spring给我们提供了一个扩展点

可以通过implement  MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition方法进行扩展

4.对于循环依赖的解决,可以看到在还没有进行bean属性赋值前暴露一个objectFactory

 

 其中getEarlyBeanReference方法

仅仅是通过 SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法将上面创建的bean引用暴露出去,如果后面程序继续调用方法

因为是同一个引用所以原bean做了赋值,依赖方的bean也会 赋值。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值