到目前為止,我們知道Spring創建Bean對象有5中方法,分別是: 使用FactoryBean的getObject方法創建 使用BeanPostProcessor的子介面InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiati ...
到目前為止,我們知道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
,一個是在初始化完之後調用,一個是容器銷毀時調用。
未完待續.....