spring源码之实例化

导读:本篇文章讲解 spring源码之实例化,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

spring中bean的实例化:
一、实例化factoryMethod方法对应的实例
二、实例化带有@Autowired注解的构造函数
三、实例化没有@Autowired注解的构造函数
四、实例化无参构造函数

一、实例化factoryMethod方法对应的实例

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		...
		...
		...
		//如果有FactoryMethodName属性 @Bean
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}
		...
		...
	}

如果mbd.getFactoryMethodName() != null 有两种情况
1、标签里面配置了factory-method属性
2、方法上面加上@Bean注解

<bean id="factoryMethodBean" class="com.study.dongsq.factoryMethod.FactoryMethodBean" />

<bean id="dongsq" factory-bean="factoryMethodBean" factory-method="factoryMethod"/>


public class FactoryMethodBean {
    public Student factoryMethod() {
        return new Student();
    }
}

在这里插入图片描述
说明:以上xml中的配置,factoryMethod只能是非静态方法
如果没有配置factory-bean属性,则必须配置class,并且factory-method必须为静态方法。

源码分析:

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

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

		Object factoryBean;
		Class<?> factoryClass;
		boolean isStatic;

		//获取factoryBean name
		String factoryBeanName = mbd.getFactoryBeanName();
		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();
			//factoryMethod要为非静态方法
			isStatic = false;
		}
		else {
			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();
			//factoryMethod需要为静态方法
			isStatic = true;
		}
		...
		...

		if (factoryMethodToUse == null || argsToUse == null) {
			factoryClass = ClassUtils.getUserClass(factoryClass);

			List<Method> candidates = null;
			...
			...
			if (candidates == null) {
				candidates = new ArrayList<>();
				//获取factoryBean中所有的方法
				Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
				for (Method candidate : rawCandidates) {
					//jdk api 判断方法是否静态和判断是否fatoryMethod
					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);
				//fatoryMethod方法不允许有参数
				if (uniqueCandidate.getParameterCount() == 0) {
					mbd.factoryMethodToIntrospect = uniqueCandidate;
					synchronized (mbd.constructorArgumentLock) {
						mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
						mbd.constructorArgumentsResolved = true;
						mbd.resolvedConstructorArguments = EMPTY_ARGS;
					}
					//在instantiate方法中进行facotryMehtod方法的反射调用
					bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
					return bw;
				}
			}
			...
		}
		...
		...
	}

二、实例化带有@Autowired注解的构造函数

示例:

@Component
public class AutowiredConstructorBean {

	@Autowired(required = false)
	public AutowiredConstructorBean(StudentA s1, StudentB s2){
		System.out.println(s1);
		System.out.println(s2);
	}

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

说明:
1、@Autowired注解的方法或者属性都会触发getBean操作。
2、@Autowired有参构造函数,@Autowired注解required属性默认为true,所以默认只能有一个@Autowired有参构造函数,如果定义多个@Autowired有参构造函数,需要将每个required属性变为false,并且spring会按照构造函数入参个数进行排序,取数量最多的进行调用完成实例化。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		...
		...
		//寻找当前正在实例化的bean中构造函数(包括有@Autowired注解的)
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}
		...
	}

@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
		throws BeansException {

	if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
		//获取所有的beanPostProcessors, beanPostProcessors是在
		//AbstractApplicationContext类的registerBeanPostProcessors方法中完成的实例化
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
				if (ctors != null) {
					return ctors;
				}
			}
		}
	}
	return null;
}

@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
		throws BeanCreationException {
	...
	...
	try {
		//获取bean对应的所有构造器
		rawCandidates = beanClass.getDeclaredConstructors();
	}
	...
	...
	for (Constructor<?> candidate : rawCandidates) {
		...
		...
		//获取到构造函数上的@Autowired注解信息
		MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
		...
		...
		if (ann != null) {
			...
			...
			//获取到@Autowired里面的required方法的值
			boolean required = determineRequiredStatus(ann);
			if (required) {
				//第一次循环candidates集合为空,
				//再次循环遍历构造函数时,required属性为true则报错
				if (!candidates.isEmpty()) {
					throw new BeanCreationException(beanName,
							"Invalid autowire-marked constructors: " + candidates +
							". Found constructor with 'required' Autowired annotation: " +
							candidate);
				}
				requiredConstructor = candidate;
			}
			candidates.add(candidate);
		}
		else if (candidate.getParameterCount() == 0) {
			defaultConstructor = candidate;
		}
	}
	...
	...
}

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

	...
	//构造函数排序,按数量排序
	AutowireUtils.sortConstructors(candidates);
	...
	for (Constructor<?> candidate : candidates) {
		int parameterCount = candidate.getParameterCount();

		//如果之前的构造器已经有一个被处理过,则后面的构造器就不用处理了
		if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
			break;
		}
		...
		if (resolvedValues != null) {
			try {
				...
				...
				//这里会触发构造函数中参数的getBean操作,会实例化参数的值
				//调用链很长,会调用到DependencyDescriptor中的resolveCandidate方法,在这里出发getBean操作
				argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
						getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
			}
			...
			...
		}
		...
		//这里会调用构造函数的api,在堆内存划分一个空间
		bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
		...
	}

三、实例化没有@Autowired注解的构造函数

示例:

@Component
public class AutowiredConstructorBean {

	public AutowiredConstructorBean(StudentA s1, StudentB s2){
		System.out.println(s1);
		System.out.println(s2);
	}

	public AutowiredConstructorBean(StudentA s1){
		System.out.println(s1);
	}

	public AutowiredConstructorBean(){

	}
}

说明:
1、实例化没有@Autowired注解的构造函数,在没有默认构造函数的情况下,只允许有一个带参数的
2、如果有多个带参数的构造函数,则必须添加默认的构造函数
3、正因为有的情况必须添加默认的构造函数,但不能强制开发者必须添加,所以才有了@Autowired有参构造函数
4、实例化没有@Autowired注解的构造函数,在有多个构造函数时,实例化走的是无参构造函数

代码解析如果有多个带参数的构造函数,则必须添加默认的构造函数

//candidates为@Autowired注解收集的构造函数
if (!candidates.isEmpty()) {
						// Add default constructor to list of optional constructors, as fallback.
	if (requiredConstructor == null) {
		if (defaultConstructor != null) {
			candidates.add(defaultConstructor);
		}
		else if (candidates.size() == 1 && logger.isInfoEnabled()) {
			logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
					"': single autowire-marked constructor flagged as optional - " +
					"this constructor is effectively required since there is no " +
					"default constructor to fall back to: " + candidates.get(0));
		}
	}
	candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
//如果构造函数有一个,且参数个数大于0,不满足
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
	candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
//默认构造函数不为空,单这一个条件就不满足
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
		defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
	candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
//构造函数有两个,不满足
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
	candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
else {
	candidateConstructors = new Constructor<?>[0];
}
//最后拿到的构造函数集合为空, 接下来调用instantiate方法完成实例化
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
	...
	...
	//这里无参构造函数为空,在这报jdk的错误
	constructorToUse = clazz.getDeclaredConstructor();
	...
	...
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/13829.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!