日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

SpringBoot如何實現Tomcat自動配置

瀏覽:142日期:2023-03-21 14:25:57

目錄

準備工作

我們知道SpringBoot的自動裝配的秘密在 org.springframework.boot.autoconfigure 包下的 spring.factories 文件中,而嵌入Tomcat的原理就在這個文件中加載的一個配置類: org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration

@Configuration@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)@ConditionalOnClass(ServletRequest.class)@ConditionalOnWebApplication(type = Type.SERVLET)@EnableConfigurationProperties(ServerProperties.class)@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,ServletWebServerFactoryConfiguration.EmbeddedJetty.class,ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })public class ServletWebServerFactoryAutoConfiguration {@Beanpublic ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties) {return new ServletWebServerFactoryCustomizer(serverProperties);}@Bean@ConditionalOnClass(name = 'org.apache.catalina.startup.Tomcat')public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) {return new TomcatServletWebServerFactoryCustomizer(serverProperties);}/** * Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via * {@link ImportBeanDefinitionRegistrar} for early registration. */public static class BeanPostProcessorsRegistrarimplements ImportBeanDefinitionRegistrar, BeanFactoryAware {private ConfigurableListableBeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {if (beanFactory instanceof ConfigurableListableBeanFactory) {this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;}}@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry) {if (this.beanFactory == null) {return;}registerSyntheticBeanIfMissing(registry,'webServerFactoryCustomizerBeanPostProcessor',WebServerFactoryCustomizerBeanPostProcessor.class);registerSyntheticBeanIfMissing(registry,'errorPageRegistrarBeanPostProcessor',ErrorPageRegistrarBeanPostProcessor.class);}private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry,String name, Class<?> beanClass) {if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);beanDefinition.setSynthetic(true);registry.registerBeanDefinition(name, beanDefinition);}}}}

首先看一下上方的幾個注解

@AutoConfigureOrder 這個注解是決定配置類的加載順序的,當注解里的值越小越先加載,而 Ordered.HIGHEST_PRECEDENCE 的值是 Integer.MIN_VALUE 也就是說這個類肯定是最先加載的那一批 @ConditionalOnXXX 在之前的文章中已經無數次提到了,就不再闡述了 @EnableConfigurationProperties 開啟 ServerProperties 類的屬性值配置。而這個類里面包含的就是Web服務的配置

@ConfigurationProperties(prefix = 'server', ignoreUnknownFields = true)public class ServerProperties {private Integer port;private InetAddress address;@NestedConfigurationPropertyprivate final ErrorProperties error = new ErrorProperties();private Boolean useForwardHeaders;private String serverHeader;private int maxHttpHeaderSize = 0; // bytesprivate Duration connectionTimeout;@NestedConfigurationPropertyprivate Ssl ssl;@NestedConfigurationPropertyprivate final Compression compression = new Compression();@NestedConfigurationPropertyprivate final Http2 http2 = new Http2();private final Servlet servlet = new Servlet();private final Tomcat tomcat = new Tomcat();private final Jetty jetty = new Jetty();private final Undertow undertow = new Undertow();}

這個類的代碼太多了,這里就不一一貼出來了,我們平常在 application.properties 中配置的server.xxx就是這個類中屬性

@ImportBeanPostProcessorsRegistrarpublic static class BeanPostProcessorsRegistrarimplements ImportBeanDefinitionRegistrar, BeanFactoryAware {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry) {if (this.beanFactory == null) {return;}registerSyntheticBeanIfMissing(registry,'webServerFactoryCustomizerBeanPostProcessor',WebServerFactoryCustomizerBeanPostProcessor.class);registerSyntheticBeanIfMissing(registry,'errorPageRegistrarBeanPostProcessor',ErrorPageRegistrarBeanPostProcessor.class);}private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry,String name, Class<?> beanClass) {if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);beanDefinition.setSynthetic(true);registry.registerBeanDefinition(name, beanDefinition);}}}

這個類注冊了兩個bean: WebServerFactoryCustomizerBeanPostProcessor 和 ErrorPageRegistrarBeanPostProcessor 關于這兩個bean的作用稍后再詳細介紹

EmbeddedTomcat

@Configuration@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)public static class EmbeddedTomcat { @Bean public TomcatServletWebServerFactory tomcatServletWebServerFactory() { return new TomcatServletWebServerFactory(); }}

這個類會在存在Tomcat相關jar包時添加一個 TomcatServletWebServerFactory bean

其他兩個相信大家都知道怎么回事了

除了這些這個類還注入了兩個類 ServletWebServerFactoryCustomizer 和 TomcatServletWebServerFactoryCustomizer現在前期準備工作已經做好了,看一下這個Tomcat是如何啟動的吧

啟動

啟動入口在 ServletWebServerApplicationContext 中的 onRefresh 方法

protected void onRefresh() {super.onRefresh(); try { createWebServer(); }catch (Throwable ex) {throw new ApplicationContextException('Unable to start web server', ex);}}

Tomcat的啟動就在 createWebServer 方法里面了

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();}

首先看一下 getWebServerFactory

protected ServletWebServerFactory getWebServerFactory() { // 這里獲取的beanname就是上方注冊的tomcatServletWebServerFactory了 String[] beanNames = getBeanFactory() .getBeanNamesForType(ServletWebServerFactory.class); if (beanNames.length == 0) { throw new ApplicationContextException( 'Unable to start ServletWebServerApplicationContext due to missing ' + 'ServletWebServerFactory bean.'); } if (beanNames.length > 1) { throw new ApplicationContextException( 'Unable to start ServletWebServerApplicationContext due to multiple ' + 'ServletWebServerFactory beans : ' + StringUtils.arrayToCommaDelimitedString(beanNames)); } return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);}

準備環境里注冊的bean現在出來一個了。注意,上方還注冊了一個后置處理器 EmbeddedServletContainerCustomizerBeanPostProcessor ,獲取bean tomcatServletWebServerFactory 的時候就會執行后置處理器的 postProcessBeforeInitialization 方法

public Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException {if (bean instanceof WebServerFactory) {postProcessBeforeInitialization((WebServerFactory) bean);}return bean;}private void postProcessBeforeInitialization(WebServerFactory webServerFactory) { LambdaSafe .callbacks(WebServerFactoryCustomizer.class, getCustomizers(), webServerFactory) .withLogger(WebServerFactoryCustomizerBeanPostProcessor.class) .invoke((customizer) -> customizer.customize(webServerFactory));}private Collection<WebServerFactoryCustomizer<?>> getCustomizers() { if (this.customizers == null) { // Look up does not include the parent context this.customizers = new ArrayList<>(getWebServerFactoryCustomizerBeans()); this.customizers.sort(AnnotationAwareOrderComparator.INSTANCE); this.customizers = Collections.unmodifiableList(this.customizers); } return this.customizers;}@SuppressWarnings({ 'unchecked', 'rawtypes' })private Collection<WebServerFactoryCustomizer<?>> getWebServerFactoryCustomizerBeans() { return (Collection) this.beanFactory .getBeansOfType(WebServerFactoryCustomizer.class, false, false).values();}

這個處理器的作用是獲得所有定制器,然后執行定制器的方法

接著往下看

這個時候就可以啟動Tomcat了

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);}protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { return new TomcatWebServer(tomcat, getPort() >= 0);}public TomcatWebServer(Tomcat tomcat, boolean autoStart) { Assert.notNull(tomcat, 'Tomcat Server must not be null'); this.tomcat = tomcat; this.autoStart = autoStart; initialize();}private void initialize() throws WebServerException { TomcatWebServer.logger.info('Tomcat initialized with port(s): ' + getPortsDescription(false)); synchronized (this.monitor) { try { addInstanceIdToEngineName(); Context context = findContext(); context.addLifecycleListener((event) -> { if (context.equals(event.getSource()) && Lifecycle.START_EVENT.equals(event.getType())) { // Remove service connectors so that protocol binding doesn’t // happen when the service is started. removeServiceConnectors(); } }); // Start the server to trigger initialization listeners this.tomcat.start(); // We can re-throw failure exception directly in the main thread rethrowDeferredStartupExceptions(); try { ContextBindings.bindClassLoader(context, context.getNamingToken(), getClass().getClassLoader()); } catch (NamingException ex) { // Naming is not enabled. Continue } // Unlike Jetty, all Tomcat threads are daemon threads. We create a // blocking non-daemon to stop immediate shutdown startDaemonAwaitThread(); } catch (Exception ex) { throw new WebServerException('Unable to start embedded Tomcat', ex); } }}

以上就是SpringBoot如何實現Tomcat自動配置的詳細內容,更多關于SpringBoot實現Tomcat自動配置的資料請關注好吧啦網其它相關文章!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
成人在线观看免费视频| 日韩欧美精品综合| 三级小说欧洲区亚洲区| 国产精品精品国产一区二区| 精品女同一区二区三区在线观看| 国产精品综合| 国产精品调教| 国产日产一区| 国产精品一区二区三区www| 91成人福利| 国产亚洲精品美女久久| 国产精品一区二区三区美女 | 久热综合在线亚洲精品| 欧美日韩国产综合网| 中文国产一区| 日韩中文字幕一区二区三区| 在线精品观看| 国产亚洲一区二区三区啪| 国产精品扒开腿做爽爽爽软件| 国产精品22p| 97精品在线| 国产综合精品| 蜜桃伊人久久| 亚洲永久字幕| 午夜久久av | 91九色综合| 欧美国产中文高清| 福利在线一区| 午夜久久久久| 亚洲精品在线a| 蜜桃久久久久| 欧美天堂视频| 午夜日韩福利| 91精品国产自产在线丝袜啪| 国产一区二区三区四区五区| 91精品国产成人观看| 噜噜噜躁狠狠躁狠狠精品视频| 日本h片久久| 亚洲性色av| 日韩在线网址| 9999国产精品| 性欧美长视频| 麻豆精品视频在线观看| 激情五月综合网| 日韩av午夜在线观看| 国产一区二区三区四区| 亚洲国产不卡| 国产精品观看| 国产99精品一区| 亚洲三级网址| 亚洲黄色网址| 婷婷视频一区二区三区| 国产精品99久久精品| 99在线观看免费视频精品观看| 91成人精品观看| 欧美一级精品| 国产日韩欧美高清免费| 久久久久久久久久久妇女| 亚洲一区二区日韩| 国产不卡av一区二区| 亚洲在线免费| 欧美极品中文字幕| 国产亚洲综合精品| 精品免费视频| 综合五月婷婷| 久久国产毛片| 国产精品任我爽爆在线播放| 蜜臀av免费一区二区三区| 国产精品久久亚洲不卡| 不卡中文字幕| 精品一区二区三区中文字幕在线| 欧美日韩免费观看一区=区三区 | 蜜臀久久久99精品久久久久久| 国产日韩欧美一区在线| 99热精品在线观看| 国产videos久久| 在线精品视频一区| 久久国产小视频| 乱一区二区av| 亚洲毛片一区| 欧美精品一二| а√天堂8资源中文在线| 日本a级不卡| 国产一区成人| 日本免费一区二区三区四区| 欧美日韩调教| 久久国产福利| 亚洲高清二区| 国产精品v亚洲精品v日韩精品| 亚洲深爱激情| 久久精品国产大片免费观看| 欧美国产日韩电影| 中文字幕免费精品| 合欧美一区二区三区| 日韩在线看片| 精品午夜av| 国产精品久久久网站| 亚洲一区欧美| 好看的av在线不卡观看| 亚洲成人一区在线观看| 欧美成a人片免费观看久久五月天| 亚洲精品国产精品粉嫩| 日韩一区二区免费看| 亚洲黄色中文字幕| 国产91在线播放精品| 国产精品亚洲综合久久| 日本亚洲欧洲无免费码在线| 国产精品女主播一区二区三区 | 麻豆91精品视频| 久久精品999| 亚洲精品一级| 日韩精品欧美精品| 一区二区三区网站| 国产午夜精品一区二区三区欧美| 欧美一区三区| 999久久久精品国产| 四虎国产精品免费观看| 麻豆91在线播放| 欧美成人精品一级| 久久不卡日韩美女| 欧美经典一区| 国产精品成人一区二区不卡| 麻豆视频观看网址久久| 国产精品日本一区二区不卡视频| 国产另类在线| 欧美国产极品| 粉嫩av一区二区三区四区五区 | 欧美成a人国产精品高清乱码在线观看片在线观看久 | 日韩在线综合| 日韩精品欧美| 久久精品一区二区不卡| 欧美13videosex性极品| 日韩在线短视频| 日韩精品免费一区二区在线观看| 久久久久国产精品一区二区| 欧美肉体xxxx裸体137大胆| 成人av二区| 99在线精品视频在线观看| 亚洲一区日韩| 日本一区二区三区中文字幕| 91p九色成人| 老司机精品视频网| 激情黄产视频在线免费观看| 老司机精品视频网| 激情黄产视频在线免费观看| 久久亚洲在线| 丝袜美腿成人在线| 日韩极品在线观看| 国产精品传媒麻豆hd| 青青青免费在线视频| 蜜桃一区二区三区| 中文字幕日韩亚洲| 国产欧美在线观看免费| 久久精品国产亚洲一区二区三区| 日本午夜大片a在线观看| 午夜国产一区二区| 亚洲a成人v| 久久精品亚洲一区二区| 亚洲国产福利| 亚洲一区成人| 国产欧美69| 日韩欧美不卡| 中文在线不卡| 国产精品亚洲四区在线观看| 在线天堂资源www在线污| 一级欧洲+日本+国产| 视频一区中文字幕精品| 精品视频亚洲| 婷婷亚洲综合| 国产亚洲久久| 日韩精品91| 综合日韩在线| 色综合狠狠操| 伊人精品在线| 国产精品亚洲产品| 国产字幕视频一区二区| 日韩国产一区二| av最新在线| 亚洲精品看片| 久久电影tv| 日韩中文字幕| 蜜桃精品在线| 日本一区二区中文字幕| 国产福利片在线观看| 亚洲伊人精品酒店| 国产一区二区三区不卡视频网站| 免费不卡中文字幕在线| 欧美日本久久| 日韩精品一区二区三区免费观影| 亚洲精品乱码久久久久久蜜桃麻豆| 免费在线观看一区| 精品欧美久久| 美女视频黄久久| 国产亚洲综合精品| 日产午夜精品一线二线三线| 中文精品电影| 久久九九电影| 国产精品久久亚洲不卡| 亚洲免费成人| 国产不卡一区|