Spring解密 - Bean的加載流程
入口
public class Application {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Person person = context.getBean("person", Person.class);
System.out.println(person.toString());
}
}
BeanFactory 的由來
1.查看getBean()的源碼.
public class AbstractApplicationContext{
@Override
public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
assertBeanFactoryActive();
// getBeanFactory() 是怎么來的往枷?我們接著看
return getBeanFactory().getBean(name, requiredType);
}
}
2.應用程序的上下文
在 new ClassPathXmlApplicationContext("bean.xml"); 中去扣,跳轉到重載的構造方法中怪与,發(fā)現(xiàn)如下代碼
public class ClassPathXmlApplicationContext {
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
// 解析 bean.xml 文件
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
}
它的目的是將普通路徑解析為 類(classpath) 路徑資源名稱。多個配置文件的情況下巡语,后加載的 Bean 會覆蓋先前定義好的 Bean翎蹈,這樣做的目的是為了通過額外的XML文件來特意重寫某個 Bean。這里我們可以看到調用了一個 refresh()男公,它的作用是什么呢荤堪?
3.初始化
刷新容器
public class AbstractApplicationContext {
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 準備刷新上下文
prepareRefresh();
// 通知子類,刷新內部 BeanFactory(創(chuàng)建 BeanFactory 的入口)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
}
}
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 跟蹤該方法
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
}
初次加載完 bean.xml 后枢赔,肯定會進入到 refresh() 方法中澄阳,這個時候會做容器初始化的工作,也就是 標簽解析踏拜、Bean加載 等等工作.
創(chuàng)建 DefaultListableBeanFactory
public class AbstractRefreshableApplicationContext {
@Override
protected final void refreshBeanFactory() throws BeansException {
// 判斷是否存在
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 創(chuàng)建 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
// 然后賦值給 beanFactory 變量
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
// 提取 BeanFactory
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return this.beanFactory;
}
}
}
從上面的代碼塊中碎赢,我們可以看到 如果已經存在 beanFactory,將銷毀舊的實例速梗,然后在創(chuàng)建新的 DefaultListableBeanFactory肮塞,最后 getBeanFactory() 就可以正常使用了襟齿。
Bean 加載
整個 Bean 的裝載過程中,重點圍繞 AbstractBeanFactory
public abstract class AbstractBeanFactory {
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 別名轉換
final String beanName = transformedBeanName(name);
Object bean;
// 檢查緩存中是否存在 該 Bean 的單例(Bean默認的Scope = singleton)
// 比如容器初始化的時候或者其他地方調用過getBean枕赵,已經完成了初始化
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//執(zhí)行一次logger.isDebugEnabled()這樣的判斷花費的時間大概是寫日志時間的萬分之一
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
} else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 返回實例猜欺,F(xiàn)actoryBean 的情況下,并不是直接返回實例本身而是返回指定方法返回的實例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 存在循環(huán)依賴則報錯
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 判斷工廠中是否含有當前 Bean 的定義
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 如果沒有拷窜,查詢父工廠
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 執(zhí)行帶有 args 參數(shù)的 getBean 方法
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// 如果沒有參數(shù)开皿,執(zhí)行標準的 getBean 方法
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) { // 如果不是做類型檢查,則需要標記此 Bean 正在創(chuàng)建之中
markBeanAsCreated(beanName);
}
try {
// 將存儲XML配置文件的GernericBeanDefinition轉換成RootBeanDefinition篮昧,如果BeanName是子Bean的話會合并父類的相關屬性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 獲取依賴的 Bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}
// 終于開始創(chuàng)建 Bean 實例了赋荆,如果是單例的,那么會創(chuàng)建一個單例的匿名工廠懊昨,
// 如果是原型模式的糠睡,則不需要創(chuàng)建單例的工廠的,其他的如 request疚颊、session 作用域的,則根據自身的需要
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);// 調用默認構造函數(shù)信认,有興趣自己跟進下代碼
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 類型檢查材义,如果不能進行類型轉換,則拋出異常
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
}
一步一步的分析
轉換 BeanName
final String beanName = transformedBeanName(name);
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
去除 FactoryBean 的修飾符嫁赏,最終取指定 alias 所表示的 beanName其掂。因為有可能獲取到以 & 開頭的 FactoryBean,所以要進行轉化
加載單例
檢查緩存中是否存在 該 Bean 的單例(Bean默認的Scope = singleton)潦蝇,如容器初始化的時候或者其他地方已經調用過 getBean() 完成了初始化
Object sharedInstance = getSingleton(beanName);
默認在裝載 Bean 的時候會先去檢查 singletonObjects 是否存在款熬,如果存在直接提取緩存的。
public class DefaultSingletonBeanRegistry {
/** 保存 BeanName 和創(chuàng)建 bean 實例之間的關系 bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 保存 BeanName 和創(chuàng)建 bean 實例的工廠之間的關系 bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** 保存 BeanName 和創(chuàng)建 bean 實例之間的關系 bean name --> bean instance */
/** 與 singletonObjects 不同的是當一個單例 bean 被放到里面后攘乒,那么在 bean 在創(chuàng)建過程中贤牛,就可以通過 getBean 方法獲取到,可以用來檢測循環(huán)引用则酝。 **/
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** 保存當前所有已注冊的 bean */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 嘗試從緩存獲取實例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 若該 bean 正在加載則不處理
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 存入到緩存中
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
}
構建實例(無緩存情況)
緩存中沒有殉簸,那就當場構建一個 bean 出來,可以看到 getSingleton(String beanName, ObjectFactory<?> singletonFactory) 有兩個參數(shù)
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 記錄加載狀態(tài)沽讹,般卑,以便對循環(huán)依賴進行檢測
beforeSingletonCreation(beanName);
singletonObject = singletonFactory.getObject();
// 移除加載狀態(tài)
afterSingletonCreation(beanName);
addSingleton(beanName, singletonObject);
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
構建 ObjectFactory
此處與其說是構建 ObjectFactory ,不如說是在創(chuàng)建一個單例 Bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 對 JDK8 lambda 表達式熟悉的小伙伴就不會陌生了
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
// 劃重點了
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
創(chuàng)建 Bean
public class AbstractAutowireCapableBeanFactory {
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 首先判斷需要創(chuàng)建的bean是否可以被實例化爽雄,這個類是否可以通過類裝載器來載入蝠检。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 準備方法覆蓋
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 用 BeanPostProcessors 返回代理來替代真正的實例(如果 Bean 配置了 PostProcessor,那么這里返回的是一個代理)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 重點來了
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException ex) {
// A previously detected exception with proper bean creation context already...
throw ex;
}
catch (ImplicitlyAppearedSingletonException ex) {
// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
}
在創(chuàng)建 Bean 之前挚瘟,Spring 還做了不少工作叹谁。
- 判斷創(chuàng)建的 bean 是否可以被實例化饲梭,這個類是否可以通過 ClassLoader 來載入,根據設置的 class 屬性或根據 className 來解析 class本慕。
- 對覆蓋進行標記并驗證排拷,在 Spring 配置中存在 lookup-mothod 和 replace-method 的,這兩個配置的加載時將配置統(tǒng)一存放在 BeanDefinition 中的 methodOverrides 屬性里锅尘,這個方法的操作也是針對于這兩個配置的监氢;
- 應用初始化前的后處理器,最后創(chuàng)建 bean藤违。在 createBean() 方法里執(zhí)行完 resolveBeforeInstantiation 方法后浪腐,如果創(chuàng)建了代理且不為空的話就直接返回,否則需要進行常規(guī) bean 的創(chuàng)建顿乒,這個創(chuàng)建過程是在 doCreateBean 中完成的
初始化 Bean
上面 createBean 交給了 doCreateBean 來創(chuàng)建 bean (上面還有一個重要的方法getObjectForBeanInstance议街,在后面分析)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 實例化 Bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 根據指定 bean 使用相應策略創(chuàng)建實例(正確情況會調用無參構造函數(shù))
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 獲取實例化好的 Bean(Person person = new Person()),此處還未進行賦值
final Object bean = instanceWrapper.getWrappedInstance();
// 獲得實例化好的 class
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 記錄創(chuàng)建 Bean 的 ObjectFactory璧榄,初始化前調用 post-processors特漩,可以讓我們在 bean 實例化之前做一些定制操作
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 檢測循環(huán)依賴,是否需要提早初始化(只能解決單例Bean)
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 初始化bean實例骨杂。
Object exposedObject = bean;
try {
// 在這個方法里面初始化對象涂身,配置 xml 中的各種屬性
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// 用于銷毀方法
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
上面源碼完成的操作可以概括為以下幾點
- RootBeanDefinition 是不是單例,如果是單例先移除緩存
- 實例化 bean搓蚪,將 RootBeanDefinition 轉換為 BeanWrapper
- 使用 MergedBeanDefinitionPostProcessor蛤售,Autowired注解 就是通過此方法實現(xiàn)類型的預解析;
- 解決循環(huán)依賴問題
- 在 populateBean() 中填充屬性妒潭,配置在 XML 中的各種屬性
- 注冊到 DisposableBean 中
- 完成創(chuàng)建并返回 Bean 的實例
接下來看下 Spring 是如何創(chuàng)建 bean 實例的悴能。跟蹤 createBeanInstance() 方法
創(chuàng)建Bean實例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 獲取 beanClass , 要先確保 Bean 是正確的雳灾,已經解析到當前節(jié)點了
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);
}
}
// 根據參數(shù)解析構造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 沒有特殊處理的情況下漠酿,只需使用無參數(shù)的構造函數(shù)。
return instantiateBean(beanName, mbd);
}
可以看出如果在 RootBeanDefinition 中存在 factoryMethodName屬性佑女,或者說配置文件中配置了 factory-method记靡,那么 Spring 會嘗試使用 instantiateUsingFactoryMethod(beanName, mbd, args) 方法根據 RootBeanDefinition 中的配置生成bean實例。然后再解析構造方法并進行實例化团驱,Spring 會根據參數(shù)及類型判斷使用哪個構造方法進行實例化摸吠。判斷調用哪個構造方法的過程會采用緩存機制,如果已經解析過則不需要重復解析而是從 RootBeanDefinition 中的屬性 resolvedConstructorOrFactoryMethod 緩存的值去取嚎花,否則需再次解析寸痢。
populateBean 屬性注入
這塊代碼比較多,就不貼出來了
在 populateBean 方法的中的主要處理流程:
- InstantiationAwareBeanPostProcessor 處理器的 postProcessAfterInstantiation 方法控制程序是否繼續(xù)填充屬性紊选;
- 根據注入類型提取依賴的 bean啼止,并存入 PropertyValues 中道逗;
- InstantiationAwareBeanPostProcessor 處理器的 postProcessPropertyValues 方法對屬性在填充前再次處理(主要還是驗證屬性);
- 將所有 PropertyValues 中的屬性填充到 BeanWrapper 中献烦;
initializeBean 初始化Bean
Spring 的 bean 配置時有一個 init-method 屬性滓窍,這個屬性的作用是在 bean 實例化前調用 init-method 指定的方法進行需要的操作,現(xiàn)在就進入這個方法了巩那;Spring 執(zhí)行過 bean 的實例化吏夯,并且進行屬性填充后,就會調用用戶設定的初始化方法即横。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 特殊bean處理
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 調用配置的 init-method
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
最后加載完 Bean 并執(zhí)行完初始化操作后噪生,一個 bean 的加載基本就結束了。
增強的 Bean
通過上面的描述东囚,我們已經知道了一個的 Bean 是如何初始化的跺嗽,已經具備普通 Bean 的功能。但是 Spring 還提供了一種增強的 Bean(FactoryBean)页藻,具備 factory 能力的 Bean桨嫁,這個能力主要在 getObjectForBeanInstance 得到。
public class AbstractBeanFactory {
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 如果想要獲取 FactoryBean 本身,那么 beanInstance 必須是 FactoryBean 的實例
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// 如果 instance 不是 FactoryBean 實例,或者想要獲取的就是 FactoryBean 實例份帐,那么直接返回就好
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
// 獲取緩存的實例
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// 緩存中沒有對象,那么從頭準備 bean defition 實例化一個
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 在這里面獲得最終的FactoryBean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
}