準備
将spring5.1源碼導入到idea編寫幾個測試類
public class Main {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
Text02 text02= (Text02)app.getBean("text02");
text02.text();
}
}
public class Text02 {
@Autowired
private MZZ02 mzz02;
public Text02(){
System.out.println("構造器Text02");
}
public void text(){
String text02 = mzz02.demo("Text02");
System.out.println("text02:"+text02);
}
@Component
public class MZZ02 {
public MZZ02(){
System.out.println("MZZ02");
}
public String demo(String text){
System.out.println("MZZ02接收:"+text);
return text+":MZZ02";
}
}
spring.xml配置如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<bean id="text02" class="laixx.bean.Text02"></bean>
//掃包
<context:component-scan base-package="laixx.cont"/>
</beans>
進入ClassPathXmlApplicationContext類
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
//将配置檔案注入到AbstractRefreshableConfigApplicationContext類的成員屬性中
setConfigLocations(configLocations);
//refresh為true
if (refresh) {
refresh();
}
}
//這個是上面的setConfigLocations方法,目的是把配置檔案設定到configLocations數組中
public void setConfigLocations(@Nullable String... locations) {
if (locations != null) {
Assert.noNullElements(locations, "Config locations must not be null");
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
this.configLocations[i] = resolvePath(locations[i]).trim();
}
}
else {
this.configLocations = null;
}
}
進入refresh();方法
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//為重新整理準備新的 context,設定其啟動日期和活動标志以及執行一些屬性的初始化。
// 主要是一些準備工作,不是很重要的方法
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//初始化beanfactroy
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//準備bean工廠以便在此上下文中使用
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//允許在上下文子類中對bean工廠進行後處理。
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//調用在上下文中注冊為bean的工廠處理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//注冊攔截bean建立的bean處理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//為此上下文初始化消息源。
initMessageSource();
// Initialize event multicaster for this context.
//為此上下文初始化事件多主機。
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//為此上下文初始化事件多主機。初始化特定上下文子類中的其他特殊bean
onRefresh();
// Check for listener beans and register them.
//檢查偵聽器bean并注冊它們。
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//執行個體化所有剩餘的(非lazy init)單例。
finishBeanFactoryInitialization(beanFactory);
// 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...
//重置Spring核心中常見的内省緩存,因為我們
//可能不再需要用于單例bean的中繼資料了…
resetCommonCaches();
}
}
}
其中主要的方法有
- obtainFreshBeanFactory();//初始化beanfactory,并解析xml
- invokeBeanFactoryPostProcessors(beanFactory);//調用在上下文中注冊為bean的工廠處理器
- registerBeanPostProcessors(beanFactory);//注冊攔截bean建立的bean處理器
- finishBeanFactoryInitialization(beanFactory);//執行個體化所有剩餘的(非lazy init)單例。