目录
1、Supplier方式创建对象
2、工厂方法创建对象
3、有参构造创建对象
4、无参构造创建对象
当创建Bean时,肯定是先通过反射创建该对象。只是Spring除了直接用反射实例化对象外还允许传入Supplier、或者设置factory-mtehod等方式。不论哪种方式初始化完成对象的创建后,会将该对象使用装饰器模式设置一些容器属性(丰富该对象)然后进行返回BeanWrapperImpl类型。
1、先检查beanClass类型;
2、如果存在Supplier类型的instanceSupplier存在,则调用其get方法初始化实例。
3、然后判断是否存在FactoryMethodName,是则调用instantiateUsingFactoryMethod获取(过程很复杂先不分析了)
4、如果有设置resolvedConstructorOrFactoryMethod属性则可能直接就能决定初始化的有参或者无参构造;否则就会遍历所有的SmartInstantiationAwareBeanPostProcessor,也可以指定构造器。比如只有一个有参数构造函数时则通过AutowiredAnnotationBeanPostProcessor将在这里返回构造器。如下:
@Component
public class AaaComponent {BbbComponent bbbComponent;public AaaComponent(BbbComponent bbbComponent) {this.bbbComponent = bbbComponent;}
}
5、通过参数确定构造函数进行初始化调用autowireConstructor方法
6、如果不存在工厂方法,也不存在参数构造,则调用默认无参构造函数初始化(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) {return obtainFromSupplier(instanceSupplier, beanName);}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?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);
}
1、Supplier方式创建对象
protected BeanWrapper obtainFromSupplier(Supplier> instanceSupplier, String beanName) {Object instance;String outerBean = this.currentlyCreatedBean.get();this.currentlyCreatedBean.set(beanName);// 省略try catchinstance = instanceSupplier.get();if (instance == null) {instance = new NullBean();}BeanWrapper bw = new BeanWrapperImpl(instance);initBeanWrapper(bw);return bw;
}
如果BeanDefinition发现设置了instanceSupplier属性,则调用其get方法获取到的就认为是实例对象。
但是需要将其进行包装成BeanWrapperImpl返回。所以不论使用哪种方式创建对象都会调用initBeanWrapper方法。将容器级别的ConversionService和PropertyEditor列表,都设置给所以的Bean。即这两个类型的配置即使容器级别的,也是每个Bean都拥有的。
protected void initBeanWrapper(BeanWrapper bw) {bw.setConversionService(getConversionService());registerCustomEditors(bw);
}
2、工厂方法创建对象
如果在标签中设置了factory-bean属性,或者在BeanDefinition中设置了factoryMethodName属性。那么可以直接从该指定方法中获取对象。
protected BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
instantiateUsingFactoryMethod方法太长,过程大致如下:
1、处理initBeanWrapper(如上)
2、根据factoryBeanName名称字符串,调用getBean(factoryBeanName)返回对象
3、根据对象的可用的方法,已经传入的参数等,排除其他最终决定调用方法和参数
4、调用下面的策略(CglibSubclassingInstantiationStrategy)方法实例化对象
beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args)
核心代码为:
Object result = factoryMethod.invoke(factoryBean, args)
3、有参构造创建对象
protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor>[] ctors, @Nullable Object[] explicitArgs) {return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
创建过程大致与上面的相同,最终都会调用CglibSubclassingInstantiationStrategy的instantiate方法。
4、无参构造创建对象
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {Object beanInstance;// 省略try catch代码final BeanFactory parent = this;beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);BeanWrapper bw = new BeanWrapperImpl(beanInstance);initBeanWrapper(bw);return bw;
}
无参构造的过程,上面的方法都会经历。