Spring 源码(14)Spring Bean 的创建过程(5) - 玲丶蹊
source link: https://www.cnblogs.com/redwinter/p/16268667.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
到目前为止,我们知道Spring
创建Bean
对象有5中方法,分别是:
- 使用
FactoryBean
的getObject
方法创建 - 使用
BeanPostProcessor
的子接口InstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation
方法创建 - 设置
BeanDefinition
的Supplier
属性进行创建 - 设置
BeanDefinition
的factory-method
进行创建 - 使用全过程:
getBean-->doGetBean-->createBean-->doCreateBean
反射进行创建
前面4中已经介绍,接下来介绍第5种,我们知道如果使用反射创建,那么必然要知道使用构造函数进行实例化,因为使用构造函数能够将带有参数的设置进去。
SmartInstantiationAwareBeanPostProcessor 接口
在前面讲过InstantiationAwareBeanPostProcessor
是用来提前实例化对象的,而SmartInstantiationAwareBeanPostProcessor
是InstantiationAwareBeanPostProcessor
的子接口,他是用来干啥呢?
在createBeanInstance
方法中的源码:
// 省略代码....
// 明确构造器从BeanPostProcessor中,对应的是 AutowiredAnnotationBeanPostProcessor
// 他是 SmartInstantiationAwareBeanPostProcessor 的子类,使用determineCandidateConstructors进行
// 解析构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 省略代码....
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
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;
}
可以看到这个接口是用来解析BeanClass
的构造函数的,SmartInstantiationAwareBeanPostProcessor
的实现类AutowiredAnnotationBeanPostProcessor
,这个类是用来解析确定合适的构造函数,重点解析了@Autowired
注解,并且还解析了@Value
注解和@Lookup
注解。
当解析出来构造函数之后,那么就调用autowireConstructor
方法进行实例化,解析时会new一个构造器解析器ConstructorResolver
,在解析factoryMehod
时也是使用的这个类使用的是instantiateUsingFactoryMethod
这个方法,并且解析factoryMethod
更加复杂,需要判断是否是静态的工厂创建还是实例工厂创建,而自动装配的构造解析相对来说简单一些,使用autowireConstructor
方法进行解析。
最终解析出构造方法和构造参数之后进行实例化:
// 使用合适的构造方法和构造参数进行实例化
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
private Object instantiate(
String beanName, RootBeanDefinition mbd, Constructor<?> constructorToUse, Object[] argsToUse) {
try {
// 获取实例化策略,一般使用 CglibSubClassingInstantiationStrategy
InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),
this.beanFactory.getAccessControlContext());
}
else {
// 开始实例化
return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
final Constructor<?> ctor, Object... args) {
if (!bd.hasMethodOverrides()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(ctor);
return null;
});
}
// 实例化类,反射调用
return BeanUtils.instantiateClass(ctor, args);
}
else {
// 如果方法被覆盖,lookup-method 和 replace-method
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}
如果前面的解析都没有到Bean
,那么就会使用无参构造函数进行解析:
// 省略代码....
// Preferred constructors for default construction?
// 首选的构造器为默认的创建方式,使用了@Primary注解的为首选的创建对象方式
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 调用无参构造函数实例化对象
return instantiateBean(beanName, mbd);
实例化Bean
:
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
// 实例化对象,使用反射进行创建
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
// 创建一个Bean的包装器
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
// 初始化Bean的包装器
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
这里可以看到前面使用factoryMethod
和autowireConstructor
解析构造函数进行实例化还是使用无参构造函数进行实例化都是将Bean
进行了包装,那这个包装有啥作用呢?
BeanWrapper的作用
我们先来看下前面的方法是怎么创建BeanWrapper
的:
factory-method
解析,ConstructorResolver#instantiateUsingFactoryMethod
方法:
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
// 创建一个Bean的包装器
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
// factoryBean
Object factoryBean;
// factory 工厂类
Class<?> factoryClass;
// 标识是否是静态的工厂
boolean isStatic;
// 省略代码....
}
SmartInstantiationAwareBeanPostProcessor
子类AutowiredAnnotationBeanPostProcessor
解析出构造函数,然后使用ConstructorResolver#autowireConstructor
执行:
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
// 创建一个包装器
BeanWrapperImpl bw = new BeanWrapperImpl();
// 初始化包装器
this.beanFactory.initBeanWrapper(bw);
// 构造函数
Constructor<?> constructorToUse = null;
// 构造参数
ArgumentsHolder argsHolderToUse = null;
// 需要使用的构造参数
Object[] argsToUse = null;
// 明确的构造参数不为空,则赋值给将要执行实例化的构造参数
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
// 省略代码....
}
最终都是会进行转换服务ConversionService
和PropertyEditorRegistry
的注册,一个是用来进行属性类型转换的,一个是用来属性值解析的:
protected void initBeanWrapper(BeanWrapper bw) {
// 获取转换服务放到bean的包装器中
bw.setConversionService(getConversionService());
// 注册定制的属性编辑器
registerCustomEditors(bw);
}
在前面的文章中,介绍了这两个如何使用,而且还自定义了属性编辑器和类型转换,需要的小伙伴可以去看看:
https://www.cnblogs.com/redwinter/p/16167214.html 和 https://www.cnblogs.com/redwinter/p/16241328.html
到这里Bean的实例化就完成了,接着往下看源码:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
// 从缓存中获取FactoryBean的Bean对象
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 实例化对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 从包装器中获取Bean对象
Object bean = instanceWrapper.getWrappedInstance();
// 从包装器中获取Bean类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 合并Bean
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
}
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
// 执行合并BeanDefinition
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
可以看到这里出现了一个接口MergedBeanDefinitionPostProcessor
,这个接口也是BeanPostProcessor
的子接口,那他到底是干啥用的呢?
MergedBeanDefinitionPostProcessor 接口
点击发现这个接口的实现类全是跟注解相关的,而最重要的是CommonAnnotationBeanPostProcessor
实现类,在构造函数中设置了两个注解:@PostConstruct
和 @PreDestroy
,一个是在初始化完之后调用,一个是容器销毁时调用。
未完待续.....
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK