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