重要類
BeanFactory: org.springframework.beans.factory.BeanFactory
,是一個非常純粹的 bean 容器,它是 IoC 必備的資料結構,其中 BeanDefinition 是它的基本結構。BeanFactory 內部維護著一個BeanDefinition map ,並可根據 BeanDefinition 的描述進行 bean 的建立和管理。
BeanDefinition: org.springframework.beans.factory.config.BeanDefinition
,用來描述 Spring 中的 Bean 物件,如儲存物件的類路徑、物件的屬性。
ApplicationContext: org.springframework.context.ApplicationContext
,這個是 Spring 容器,它叫做應用上下文,與我們應用息息相關。
入口
// 建立ioc容器, sMainConfig為配置類
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
// AnnotationConfigApplicationContext
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
// 讀取註解的Bean定義讀取器
private final AnnotatedBeanDefinitionReader reader;
// 掃描指定類路徑中註解Bean定義的掃描器
private final ClassPathBeanDefinitionScanner scanner;
// 無參建構函式
public AnnotationConfigApplicationContext() {
// 檢視new AnnotatedBeanDefinitionReader(this)原始碼可以發現
// 此時往容器中注入了5個處理器
// ConfigurationClassPostProcessor
// AutowiredAnnotationBeanPostProcessor
// CommonAnnotationBeanPostProcessor
// EventListenerMethodProcessor
// DefaultEventListenerFactory
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
// 最常用的建構函式,透過將涉及的配置類傳遞給該建構函式,實現將相應配置類中的Bean自動註冊到容器中
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
// (1) 呼叫無參建構函式
this();
// (2) 將配置類資訊封裝成BeanDefinition物件儲存到beanDefinitionMap容器中
register(annotatedClasses);
// (3)重新整理容器,觸發容器對註解Bean的載入、解析和註冊
refresh();
}
}
第一步
呼叫無參建構函式往容器中注入五個處理器的作用
ConfigurationClassPostProcessor:BeanFactoryPostProcessor
的子類,
1.獲取配置類的@ComponentScan(basePackages = {"xxx.xxx.xxx"})
資訊,將basePackages下的所有Bean註冊到容器中
2.獲取配置類中被@Bean
註解標註的方法,並將這些Bean註冊到容器中
AutowiredAnnotationBeanPostProcessor:BeanPostProcessor
的子類
用來實現依賴注入的功能,在AbstractAutowireCapableBeanFactory#populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
方法中執行
CommonAnnotationBeanPostProcessor
EventListenerMethodProcessor:實現了SmartInitializingSingleton
, ApplicationContextAware
, BeanFactoryPostProcessor
介面。收集容器中所有類中被@EventListener
標註的方法,當有事件釋出時,這些被標註的方法會被執行。
@Service
public class UserService {
@EventListener(classes = {ApplicationEvent.class})
public void listener(ApplicationEvent event) {
System.out.println("UserService..." + event);
}
}
呼叫時機finishBeanFactoryInitialization(beanFactory)
,將所有的Bean例項化之後,遍歷所有的Bean,判斷Bean是否實現了SmartInitializingSingleton
介面,如果實現了,那麼將呼叫SmartInitializingSingleton#afterSingletonsInstantiated()
方法,該方法用來收集容器中被@EventListener
標註的方法,將這些方法封裝成一個ApplicationListener
註冊到容器中,context.addApplicationListener(applicationListener)
。
DefaultEventListenerFactory
將類中的某個方法轉換成ApplicationListener
型別
第二步
將配置類資訊封裝成BeanDefinition物件儲存到beanDefinitionMap容器中
第三步
重新整理容器,觸發容器對註解Bean的載入、解析和註冊
// AbstractApplicationContext
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 重新整理前的預處理
prepareRefresh();
// 獲取一個BeanFactory(DefaultListableBeanFactory),
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 2. BeanFactory 的預準備
prepareBeanFactory(beanFactory);
try {
// 3. BeanFactory準備完成後的後置處理
postProcessBeanFactory(beanFactory);
// 4. 執行BeanFactoryPostProcessors的方法
invokeBeanFactoryPostProcessors(beanFactory);
// 5. 收集所有的 BeanPostProcessors
registerBeanPostProcessors(beanFactory);
// 6. 初始化上下文中的資原始檔,如國際化檔案的處理等
initMessageSource();
// 7. 初始化上下文事件廣播器
initApplicationEventMulticaster();
// 8.給子類擴充套件初始化其他Bean
onRefresh();
// 9. 在所有 bean 中查詢 listener bean,然後註冊到廣播器中
registerListeners();
// 10.初始化剩下的單例Bean(非延遲載入的)
finishBeanFactoryInitialization(beanFactory);
// 11. 完成重新整理過程,通知生命週期處理器 lifecycleProcessor 重新整理過程,同時發出 ContextRefreshEvent 通知別人
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();
}
}
}
1.prepareRefresh();
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// 留給子類處理的方法
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// 儲存容器中的一些早期的事件
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2.prepareBeanFactory(beanFactory);
BeanFactory 的預準備
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 設定BeanFactory的類載入器、支援表示式解析的.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 新增一個BeanPostProcessor
// Bean初始化時(initializeBean)用來判斷是否實現了ApplicationContextAware、MessageSourceAware等介面
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);
// 註冊可以解析的自動裝配, 可以在任何Bean中注入這些
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 新增一個BeanPostProcessor
// Bean初始化時(initializeBean)收集實現了ApplicationListener的類
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// // 增加對AspectJ的支援
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()));
}
// 註冊一些預設的環境Bean
// 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());
}
}
3.postProcessBeanFactory(beanFactory);
BeanFactory準備完成後的後置處理。這是一個空方法,子類可以重寫這個方法。
4.invokeBeanFactoryPostProcessors(beanFactory);
透過beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)
和
beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)
獲取實現了BeanDefinitionRegistryPostProcessors
介面和BeanFactoryPostProcessors
介面的類,獲取過程中會觸發Bean的例項化然後執行相應的方法。可以透過實現PriorityOrdered
、Ordered
介面來實現優先順序。
先執行postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
方法,
然後執行postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
。
前面提到的ConfigurationClassPostProcessor
類就是實現了BeanDefinitionRegistryPostProcessors
介面,而BeanDefinitionRegistryPostProcessors
繼承了BeanFactoryPostProcessors
介面。這個類的作用如下:
1.獲取配置類的@ComponentScan(basePackages = {"xxx.xxx.xxx"})
資訊,將basePackages下的所有Bean註冊到容器中
2.獲取配置類中被@Bean
註解標註的方法,並將這些Bean註冊到容器中
這一步完成後,所有的Bean都已經註冊到容器中,此時只有實現了BeanFactoryPostProcessors的類被例項化了,其它Bean都還沒有例項化。透過實現BeanFactoryPostProcessors
介面,我們可以修改BeanDefinition
的一些屬性。
5.registerBeanPostProcessors(beanFactory);
獲取所有實現了BeanPostProcessor
介面的類,並將這些類儲存在一個List列表裡面,以便後續使用。可以透過實現PriorityOrdered
、Ordered
介面來實現優先順序。此時這些類也會被例項化。Bean初始化時(initializeBean),會執行這些類的postProcessBeforeInitialization(Object bean, String beanName)
方法和postProcessAfterInitialization(Object bean, String beanName)
。
6.initMessageSource();
初始化上下文中的資原始檔,如國際化檔案的處理等 。判斷容器中是否存在id為messageSource並且型別是MessageSource的Bean,如果有則賦值給messageSource,如果沒有則自己建立一DelegatingMessageSource
,並注入到容器中。 其實該方法就是初始化一個 MessageSource 介面的實現類,主要用於國際化/i18n。
7.initApplicationEventMulticaster();
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果存在 applicationEventMulticaster bean,則獲取賦值
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
// 沒有則新建 SimpleApplicationEventMulticaster,並完成 bean 的註冊
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
如果當前容器中存在 applicationEventMulticaster 的 bean,則對 applicationEventMulticaster 賦值,否則新建一個 SimpleApplicationEventMulticaster 的物件(預設的),並完成註冊。
8.onRefresh();
預留給 AbstractApplicationContext 的子類用於初始化其他特殊的 bean,該方法需要在所有單例 bean 初始化之前呼叫。 例如在SpringBoot裡面,ServletWebServerApplicationContext實現了這個方法,在這個方法裡面開始啟動web應用伺服器,如Tomcat。
9.registerListeners();
protected void registerListeners() {
// 首先註冊指定的靜態監聽器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 獲取所有ApplicationListener型別的Bean名字然後註冊到ApplicationEventMulticaster
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 下面將釋出前期的事件給監聽器
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
10.finishBeanFactoryInitialization(beanFactory);
初始化剩下的單例Bean(非延遲載入的)
// AbstractApplicationContext
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// ....省略前面的方法
// 初始化剩下的單例Bean(非延遲載入的)
beanFactory.preInstantiateSingletons();
}
最終呼叫如下方法
// DefaultListableBeanFactory
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 獲取所有的bean名字
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 觸發所有單例的、非懶載入的Bean的例項化
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); // 此時會觸發Bean的例項化
}
}
}
else {
getBean(beanName); // 此時會觸發Bean的例項化
}
}
}
// 所有單例的、非懶載入的Bean已經全部例項化
// 收集容器中被@EventListener標註的方法,將這些方法封裝成一個ApplicationListener註冊到容器中
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();
}
}
}
}
11.finishRefresh()
完成重新整理過程,通知生命週期處理器 LifecycleProcessor 重新整理過程,同時發出 ContextRefreshEvent 通知別人
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
這個時候IOC容器就建立完成了。
本作品採用《CC 協議》,轉載必須註明作者和本文連結