spring 源碼分析(二)Core
sschrodinger
2019/03/14
參考
Spring 中 Bean 的生命周期是怎樣的?-
大閑人柴毛毛
Spring Bean Life Cycle Explained - by - Lokesh Gupta
基于 spring centext 5.1.3.RELEASE
簡介
在 spring 中匠襟,使用 Bean 代指 spring 所管理的類,如上一節(jié)的 ServiceImpl
,同時,spring 也規(guī)定了 Bean 的生命周期岔留,不同于普通類從載入到被垃圾回收器回收的生命周期,spring 實現(xiàn)了更加詳盡的生命周期检柬。spring bean 的生命周期如下:
- 實例化 bean 對象献联,即 new XX();
- 填充對象屬性
- 檢查Aware相關(guān)接口并設(shè)置相關(guān)依賴
- BeanPostProcessor 前置處理
- 檢查是否是 InitializingBean 決定是否調(diào)用 afterPropertiesSet 方法,檢查是否有自定義的 init-method何址,有的話調(diào)用
- BeanPosetProcessor 后置處理
- 注冊必要的 Destruction 相關(guān)回調(diào)接口
- 使用
- 是否實現(xiàn) DisposableBean 相關(guān)接口里逆,是的話執(zhí)行 destroy() 函數(shù)。
- 是否有自定義 destroy 方法用爪,是的話執(zhí)行原押。
詳細解釋參見大閑人柴毛毛知乎
組件簡介
BeanFactory
BeanFactory 是 spring 最基本的一個庫,BeanFactory 實現(xiàn)了 Bean 對象的管理偎血,包括如何利用 Bean 的名字獲得 Bean 對象等诸衔。BeanFactory
的接口如下:
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
//根據(jù) bean name 獲得bean 對象
Object getBean(String name) throws BeansException;
//根據(jù) bean name 獲得 bean 對象并轉(zhuǎn)化成正確類型
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
//利用 bean name 獲得 bean 對象,并用 args 覆蓋一些配置
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
boolean containsBean(String name);
//bean 是否為單例模式
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
//是否為 原型模式
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
依據(jù) BeanFactory
所派生的接口非常復(fù)雜颇玷,大概有 20 個左右的類笨农。典型的接口如下:
//顧名思義,層級 BeanFactory帖渠,可以獲得上一級 BeanFatory谒亦,并且可以判斷某名字的 Bean 是否在該 BeanFacory 中。
public interface HierarchicalBeanFactory extends BeanFactory {
BeanFactory getParentBeanFactory();
boolean containsLocalBean(String name);
}
//能夠自動注解的類
public interface AutowireCapableBeanFactory extends BeanFactory {
int AUTOWIRE_NO = 0;
int AUTOWIRE_BY_NAME = 1;
int AUTOWIRE_BY_TYPE = 2;
int AUTOWIRE_CONSTRUCTOR = 3;
@Deprecated
int AUTOWIRE_AUTODETECT = 4;
String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
<T> T createBean(Class<T> beanClass) throws BeansException;
void autowireBean(Object existingBean) throws BeansException;
Object configureBean(Object existingBean, String beanName) throws BeansException;
//-------------------------------------------------------------------------
// Specialized methods for fine-grained control over the bean lifecycle
//-------------------------------------------------------------------------
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
Object initializeBean(Object existingBean, String beanName) throws BeansException;
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
void destroyBean(Object existingBean);
//-------------------------------------------------------------------------
// Delegate methods for resolving injection points
//-------------------------------------------------------------------------
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
}
//可以計數(shù)的 BeanFactory
public interface ListableBeanFactory extends BeanFactory {
boolean containsBeanDefinition(String beanName);
int getBeanDefinitionCount();
String[] getBeanDefinitionNames();
String[] getBeanNamesForType(ResolvableType type);
String[] getBeanNamesForType(@Nullable Class<?> type);
String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
}
//最重要的一個接口,spring 中大部分的實例都是使用的該接口
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
@Nullable
String getId();
String getApplicationName();
String getDisplayName();
long getStartupDate();
@Nullable
ApplicationContext getParent();
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
ConfigurableApplicationContext
繼承自 ApplicationContext
诊霹,增加了一些配置的功能羞延,如設(shè)置 context
ID,最重要的是增加了 addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)
和 void refresh() throws BeansException, IllegalStateException
方法脾还,用于實現(xiàn) context
的刷新和初始化之前的一些操作伴箩。
BeanDefinition
用于保存每一個 bean 的定義。
BeanWrapper
用于封裝需要注入的類鄙漏,并提供 set 方式嗤谚,以避免用反射的方式設(shè)置屬性。
AbstractBeanDefinitionReader
AbstractBeanDefinitionReader
實現(xiàn)了 BeanDefinitionReader
接口和 EnvironmentCapable
接口怔蚌,主要作用是讀取配置文件并生成對應(yīng) Bean 的配置巩步。
處理流程分析
以如下的代碼分析處理流程,代碼如下:
package ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring_ioc.xml");
Service service = (Service) context.getBean("serviceImpl");
service.doSomething();
}
}
package ioc;
public interface Service {
public void doSomething();
}
package ioc;
public class ServiceImpl implements Service {
public void doSomething() {
System.out.println(this.getClass().getName() + "#doSomething");
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean name="serviceImpl" class="ioc.ServiceImpl">
</bean>
</beans>
Bean 的生命周期分為10個步驟桦踊,按照步驟一步一步說明 BeanFactory
如何管理 Bean椅野。
初始化
這里的初始化指的是 Bean 生命周期中 Bean 實例準備就緒之前的所有動作。
準備工作
Bean 的初始化始于 ApplicationContext context = new ClassPathXmlApplicationContext("spring_ioc.xml")
籍胯,總結(jié)來說就是讀取配置文件并生成實例竟闪。
ClaaPathXmlApplicationContext
是 AbstractXmlApplicationContext
的子類,作用就是從 classpath 中查找配置文件并對 Bean 進行初始化杖狼。
ClaaPathXmlApplicationContext
的初始化函數(shù)如下:
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
實際上是調(diào)用繼承的初始化函數(shù)炼蛤,并對 Bean 刷新。
super(parent)
方法在 AbstractApplicationContext
中正真執(zhí)行蝶涩,代碼如下:
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
this();
setParent(parent);
}
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
實際上作用只是獲得一個 ResourcePatternResolver
理朋。
setConfigLocations(configLocations)
用于設(shè)定 confifLocation
的位置,并存儲绿聘。
最重要的函數(shù)是 refresh
方法嗽上,通過 refresh
更新 BeanFactory
,refresh
的方法實現(xiàn)在 AbstractApplicationContext
中熄攘,具體實現(xiàn)如下:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//step 1
// Prepare this context for refreshing.
prepareRefresh();
//step 2
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//step 3
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
//step 4
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//step 5
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//step 6
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
//step 7
// Initialize message source for this context.
initMessageSource();
//step 8
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
//step 9
// Initialize other special beans in specific context subclasses.
onRefresh();
//step 10
// Check for listener beans and register them.
registerListeners();
//step 11
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//step 12
// Last step: publish corresponding event.
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
第一步
prepareRefresh()
主要是做一些檢查的工作炸裆,并將當前的 BeanFacory
的屬性設(shè)置為激活。
第二步
obtainFreshBeanFactory
是真正的初始化函數(shù)鲜屏,函數(shù)定義如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
更新 BeanFactory 并將 BeanFactory 返回。其中国拇,refreshBeanFactory()
交給了子類實現(xiàn)洛史。具體的實現(xiàn)在 AbstractRefreshableApplicationContext
中。具體代碼如下:
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
當存在 beanFactory 時酱吝,首先先注銷原來的 BeanFactory也殖,接下來創(chuàng)建一個新的內(nèi)部 BeanFactory,設(shè)置序列號,并在 customizeBeanFactory(beanFactory)
中設(shè)置是否允許覆蓋定義(默認允許)忆嗜,最重要的是 loadBeanDefinitions
函數(shù)己儒,他負責了讀取配置并對 Bean 進行加載。
loadBeanDefinitions
函數(shù)由其子類 AbstractXmlApplicationContext
實現(xiàn)捆毫。主要功能實解析 xml
文件并產(chǎn)生 Bean Definition闪湾。
解析 xml 文件
loadBeanDefinitions()
函數(shù)的實現(xiàn)如下:
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
可以看到主要是生成一個 XmlBeanDefinitionReader
實例對 xml
文件進行解析。以下的函數(shù)都是實現(xiàn)在其父類 AbstractBeanDefinitionReader
中的方法绩卤,提供通用的加載策略途样。最重要的是 loadBeanDefinitions(beanDefinitionReader)
函數(shù)。函數(shù)定義如下:
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
因為使用 configLocation 加載配置濒憋,所以 configResources 為空何暇,Resource
接口定義了資源是否存在,資源是否準備好凛驮,資源是否是文件等信息裆站,一般用于網(wǎng)絡(luò)資源的加載。我們只關(guān)心以 Stringp[]
作為參數(shù)的 loadBeanDefinitions
函數(shù)黔夭。
定義如下:
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
for (String location : locations) {
count += loadBeanDefinitions(location);
}
return count;
}
邏輯很簡單宏胯,有多少個文件就執(zhí)行多少次 loadDefinition
函數(shù),并計數(shù)纠修。真正的處理函數(shù)在 loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources)
中胳嘲。代碼如下:
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
}
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
int count = loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
if (logger.isTraceEnabled()) {
logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
}
return count;
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Could not resolve bean definition resource pattern [" + location + "]", ex);
}
} else {
// Can only load single resources by absolute URL.
Resource resource = resourceLoader.getResource(location);
int count = loadBeanDefinitions(resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (logger.isTraceEnabled()) {
logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}
return count;
}
}
在 ClassPathXmlApplicationContext
的實現(xiàn)中,他既繼承了 BeanFactory扣草,也同時繼承了 ResourceLoader
和 ResourcePatternResolver
即可以實現(xiàn)資源的加載和將 url 封裝成 Resource 的功能了牛。
url 經(jīng)過解析之后,實際上還是調(diào)用的 loadDefinifions(Resource[])
辰妙,這時鹰祸,Resource 中包含了 path 和類加載器。我們再看 loadDefinifions(Resource[])
密浑,定義如下:
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
for (Resource resource : resources) {
count += loadBeanDefinitions(resource);
}
return count;
}
loadBeanDefinitions(Resource)
由其子類重寫蛙婴,用來加載真正的資源。XmlBeanDefinitionReader
實現(xiàn)如下:
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
//EncodedResource 封裝了 encode 方法和 encode 的編碼類型
return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
//resourcesCurrentlyBeingLoaded 是一個 ThreadLocal 變量尔破,用于安全的線程中存儲數(shù)據(jù).
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
//將 encodedResource 添加到 ThreadLocal 中街图。
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//解析數(shù)據(jù)
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} finally {
inputStream.close();
}
} catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
} finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
catch...
}
doLoadBeanDefinitions
主要有兩個步驟,第一個步驟是獲得 xml 的 Document 文檔懒构,第二個步驟是將文檔中的 Bean 定義注冊到 context 中餐济。
第一個步驟的代碼如下:
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
//生成 Document,利用 EntityResolver 解析 SAX 文件(DTD等)胆剧,生成Document
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}
第二個步驟的代碼如下:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
Registry
是存儲 Bean 的結(jié)構(gòu)絮姆,在這里,默認使用 DefaultListableBeanFactory
實現(xiàn)。解析 Document 文件并根據(jù)解析結(jié)果將 BeanDefinition 存儲在 Regist 中篙悯。
第三步
prepareBeanFactory
主要是對 beanFactory 做一些初始化蚁阳,比如說設(shè)置 classLoader,忽略的接口鸽照,并提前注冊一些 Bean螺捐,如使用 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory)
函數(shù)注冊他自身,或者注冊單例模式(使用 beanFactory.registerSingleton()
函數(shù))移宅。代碼如下:
/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
第四步
postProcessBeanFactory(beanFactory)
允許子類對 beanFactory 做一些自定義的操作归粉,這里沒有實現(xiàn),是一個空方法漏峰。
第五步
invokeBeanFactoryPostProcessors
實例化所有注冊的的 BeanFactoryPostProcessor Bean糠悼。
第六步
registerBeanPostProcessors(beanFactory)
注冊預(yù)處理器。
第七步
initMessageSource()
浅乔,初始化數(shù)據(jù)源倔喂。
第八步
initApplicationEventMulticaster()
,初始化多播器靖苇。
第九步
onRefresh()
席噩,更新。子類未實現(xiàn)贤壁。
第十步
registerListeners()
第九步悼枢,注冊監(jiān)聽器
第十一步
finishBeanFactoryInitialization()
初始化所有剩下的Beans,集體實現(xiàn)如下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
//此時禁止配置脾拆,以防止出現(xiàn)不可預(yù)料的問題
beanFactory.freezeConfiguration();
//初始化剩下的單例 Bean
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
重點函數(shù)在 preInstantiateSingletons
上馒索。這個函數(shù)負責真正加載單例 Bean。代碼如下:
@Override
public void preInstantiateSingletons() throws BeansException {
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
} else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
首先獲得所有 Bean 的名字名船,通過名字獲得 BeanDefinition绰上,如果不是 FactoryBean 的話,執(zhí)行 getBean(beanName)
渠驼。
getBean()
由 doGetBean()
具體實現(xiàn)蜈块,實現(xiàn)是在 AbstractBeanFactory
中,具體實現(xiàn)如下:
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;
// phase 1
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// phase 2
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
} else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// phase 3
// Guarantee initialization of beans that the current bean depends on.
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);
try {
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// phase 4
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
} 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;
}
}
// Check if required type matches the type of the actual bean instance.
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) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
代碼非常的長迷扇,將其分段百揭。
第一階段,主要是在人工注入的 Register 中有沒有 Bean蜓席,如果有信峻,返回。
第二階段瓮床,檢查父節(jié)點中有沒有 Bean,有,返回隘庄。
第三階段踢步,主要是檢查 有沒有循環(huán)依賴,循環(huán)依賴的報錯就是在這產(chǎn)生的丑掺。并且初始化所有的依賴 Bean获印。
第四階段,調(diào)用 createBean(beanName, mbd, args)
新建一個單例 bean街州。在這一階段兼丰,做了生命周期中大量的工作,包括初始化 Bean唆缴、填充屬性鳍征、如果繼承自 BeanNameAware,設(shè)置 Bean name面徽、如果繼承自 BeanFactoryAware艳丛,設(shè)置 BeanFactory、調(diào)用BeanPostProcessor
的 postProcessBeforeInitialization
做一些前期處理趟紊、如果繼承了 InitializingBean
接口氮双,則調(diào)用 afterPropertiesSet
方法、如果繼承了 BeanPostProcess
接口霎匈,則調(diào)用 postProcessAfterInitialization
方法戴差。可以說铛嘱,這一步暖释,實現(xiàn)了 Bean 大部分的生命周期函數(shù)。
第十二步
finishRefresh()
弄痹,主要是做一些收尾工作饭入。
至此,初始化 Bean 的工作九到此結(jié)束肛真。
使用過程
使用過程和初始化復(fù)用了大量的代碼谐丢,主要是 getBean()
函數(shù)的代碼,唯一的區(qū)別是在初始化時蚓让,要新建實例乾忱,而使用時直接從緩存中讀取數(shù)據(jù)并返回。