他會(huì)調(diào)用 ((AbstractApplicationContext) applicationContext).refresh();方法,我們點(diǎn)進(jìn)來看
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
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...
resetCommonCaches();
}
}
}
這點(diǎn)代碼似曾相識(shí)啊 沒錯(cuò),就是一個(gè)spring的bean的加載過程我在,解析springIOC加載過程的時(shí)候介紹過這里面的方法,如果你看過Spring源碼的話 ,應(yīng)該知道這些方法都是做什么的。現(xiàn)在我們不關(guān)心其他的,我們來看一個(gè)方法叫做 onRefresh();方法
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
他在這里并沒有實(shí)現(xiàn),但是我們找他的其他實(shí)現(xiàn),我們來找

我們既然要找Tomcat那就肯定跟web有關(guān),我們可以看到有個(gè)ServletWebServerApplicationContext
@Override
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
我們可以看到有一個(gè)createWebServer();方法他是創(chuàng)建web容器的,而Tomcat不就是web容器,那他是怎么創(chuàng)建的呢,我們繼續(xù)看
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
ServletWebServerFactory factory = getWebServerFactory();
this.webServer = factory.getWebServer(getSelfInitializer());
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context",
ex);
}
}
initPropertySources();
}
factory.getWebServer(getSelfInitializer());他是通過工廠的方式創(chuàng)建的
public interface ServletWebServerFactory {
WebServer getWebServer(ServletContextInitializer... initializers);
}
可以看到 它是一個(gè)接口,為什么會(huì)是接口。因?yàn)槲覀儾恢故荰omcat一種web容器。

我們看到還有Jetty,那我們來看TomcatServletWebServerFactory
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
File baseDir = (this.baseDirectory != null) ? this.baseDirectory
: createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat);
}
那這塊代碼,就是我們要尋找的內(nèi)置Tomcat,在這個(gè)過程當(dāng)中,我們可以看到創(chuàng)建Tomcat的一個(gè)流程。因?yàn)閞un方法里面加載的東西很多,所以今天就淺談到這里。如果不明白的話, 我們?cè)谟昧硪环N方式來理解下,
大家要應(yīng)該都知道stater舉點(diǎn)例子
<dependency>
<groupId>org.springframework.boot<span class="hljs-name"groupId>
<artifactId>spring-boot-starter-data-redis<span class="hljs-name"artifactId>
<span class="hljs-name"dependency>
<dependency>
<groupId>org.springframework.boot<span class="hljs-name"groupId>
<artifactId>spring-boot-starter-freemarker<span class="hljs-name"artifactId>
<span class="hljs-name"dependency>
所以我們不防不定義一個(gè)stater來理解下,我們做一個(gè)需求,就是定制化不同的人跟大家說你們好,我們來看
<parent>
<groupId>org.springframework.boot<span class="hljs-name"groupId>
<artifactId>spring-boot-starter-parent<span class="hljs-name"artifactId>
<version>2.1.4.RELEASE<span class="hljs-name"version>
<relativePath/>
<span class="hljs-name"parent>
<groupId>com.zgw<span class="hljs-name"groupId>
<artifactId>gw-spring-boot-srater<span class="hljs-name"artifactId>
<version>1.0-SNAPSHOT<span class="hljs-name"version>
<dependencies>
<dependency>
<groupId>org.springframework.boot<span class="hljs-name"groupId>
<artifactId>spring-boot-autoconfigure<span class="hljs-name"artifactId>
<span class="hljs-name"dependency>
<span class="hljs-name"dependencies>
我們先來看maven配置寫入版本號(hào),如果自定義一個(gè)stater的話必須依賴spring-boot-autoconfigure這個(gè)包,我們先看下項(xiàng)目目錄

public class GwServiceImpl implements GwService{
@Autowired
GwProperties properties;
@Override
public void Hello()
{
String name=properties.getName();
System.out.println(name+"說:你們好啊");
}
}
我們做的就是通過配置文件來定制name這個(gè)是具體實(shí)現(xiàn)
@Component
@ConfigurationProperties(prefix = "spring.gwname")
public class GwProperties {
String name="zgw";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
這個(gè)類可以通過@ConfigurationProperties讀取配置文件
@Configuration
@ConditionalOnClass(GwService.class) //掃描類
@EnableConfigurationProperties(GwProperties.class) //讓配置類生效
public class GwAutoConfiguration {
/**
* 功能描述 托管給spring
* @author zgw
* @return
*/
@Bean
@ConditionalOnMissingBean
public GwService gwService()
{
return new GwServiceImpl();
}
}
這個(gè)為配置類,為什么這么寫因?yàn)椋瑂pring-boot的stater都是這么寫的,我們可以參照他仿寫stater,以達(dá)到自動(dòng)配置的目的,然后我們?cè)谕ㄟ^spring.factories也來進(jìn)行配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.gw.GwAutoConfiguration
然后這樣一個(gè)簡單的stater就完成了,然后可以進(jìn)行maven的打包,在其他項(xiàng)目引入就可以使用,在這里列出代碼地址
-
XML
+關(guān)注
關(guān)注
0文章
188瀏覽量
34527 -
spring
+關(guān)注
關(guān)注
0文章
341瀏覽量
15933 -
Boot
+關(guān)注
關(guān)注
0文章
154瀏覽量
37736 -
注解
+關(guān)注
關(guān)注
0文章
18瀏覽量
2849 -
SpringBoot
+關(guān)注
關(guān)注
0文章
177瀏覽量
684
發(fā)布評(píng)論請(qǐng)先 登錄
Spring Boot的注解原理是什么
Spring Boot中常見的各類型注解的使用方式
Spring Boot常用注解與使用方式
求一種SpringBoot定時(shí)任務(wù)動(dòng)態(tài)管理通用解決方案
Java注解及其底層原理解析2
什么是 SpringBoot?
SpringBoot常用注解及使用方法1
SpringBoot常用注解及使用方法2
Springboot常用注解合集
SpringBoot常用注解及原理
SpringBoot的核心注解1
SpringBoot的核心注解2
評(píng)論