欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot實現(xiàn)嵌入式 Servlet容器

 更新時間:2023年12月06日 10:31:48   作者:程序猿進階  
傳統(tǒng)的Spring MVC工程部署時需要將WAR文件放置在servlet容器的文檔目錄內(nèi),而Spring Boot工程使用嵌入式servlet容器省去了這一步驟,本文就來設(shè)置一下相關(guān)配置,感興趣的可以了解一下

一、如何定制和修改Servlet容器的相關(guān)配置

前言: SpringBootWeb環(huán)境下,默認使用的是Tomact作為嵌入式的Servlet容器;

在這里插入圖片描述

【1】修改和server相關(guān)的配置(ServerProperties實現(xiàn)了EmbeddedServletContainerCustomizer)例如:修改端口號

#通用的Servlet容器設(shè)置:修改端口號
server:
  port: 8081
  tomcat:  #設(shè)置Tomact的相關(guān)屬性,例如編碼格式
    uri-encoding: utf-8

? 我們也可以進入port所屬的對象中,發(fā)現(xiàn)其他可修改的參數(shù)等等,如下:

@ConfigurationProperties(
    prefix = "server",
    ignoreUnknownFields = true
)
public class ServerProperties implements EmbeddedServletContainerCustomizer, EnvironmentAware, Ordered {
    private Integer port;
    private InetAddress address;
    private String contextPath;
    private String displayName = "application";
    ......

【2】編寫一個EmbeddedServletContainerCustomizer:嵌入式的 Servlet容器的定制器,來修改 Servlet容器的配置。其實1中的 ServerProperties也是實現(xiàn)了 EmbeddedServletContainerCustomizer。xxxCustomizer 幫組我們進行定制配置。

@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    @Bean
    public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
        return new EmbeddedServletContainerCustomizer() {
            @Override
            public void customize(ConfigurableEmbeddedServletContainer container) {
                container.setPort(8082);
            }
        };
    }

二、注冊Servlet三大組件【Servlet、Filter、Listener】

由于SpringBoot默認是以 jar包的方式啟動嵌入的Servlet容器來啟動SpringBootweb應(yīng)用,沒有web.xml文件。注冊三大組件的方式如下:

【1】通過 ServletRegistrationBean注冊自定義的Servlet。

//首先創(chuàng)建一個Servlet
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Hello MyServlet");
        super.doPost(req, resp);
    }
}

//將創(chuàng)建的Servlet通過配置類注入到容器中,兩個是不同的類。
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    @Bean
    public ServletRegistrationBean myServlet(){
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(), "/myServlet");
        return registrationBean;
    }

【2】通過 FilterRegistrationBean 注冊攔截器 Filter。

//自定義一個filter實現(xiàn)servlet.Filter接口
public class myFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.printf("myFilter");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

//通過配置類注入自定義的Filter
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    @Bean
    public FilterRegistrationBean myFilter(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new myFilter());
        registrationBean.setUrlPatterns(Arrays.asList("/hello","/myFilter"));
        return registrationBean;
    }
【3】通過`ServletListenerRegistrationBean`注冊自定義的`Listener`。
```java
//創(chuàng)建自定義的Listener監(jiān)聽
public class myListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.printf("服務(wù)啟動");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.printf("服務(wù)銷毀");
    }
}

//通過配置類注入自定義的listener
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {

    public ServletListenerRegistrationBean myListener(){
        ServletListenerRegistrationBean<MyListener> servletListenerRegistrationBean = new ServletListenerRegistrationBean<>(new MyListener());
        return servletListenerRegistrationBean;
    }

三、使用其他 Servlet容器:Jetty(長連接引用)、Undertow(不支持JSP)

【1】我們在定制嵌入式的Servlet容器時,會傳入ConfigurableEmbeddedServletContainer類,我們通過Ctrl+T查看此可配置嵌入式類容器中可以配置Tomcat、JettyUndertow

//ConfigurableEmbeddedServletContainer 
@Bean
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            container.setPort(8082);
        }
    };
}

【2】默認使用Tomcat,因為starter-web引入的是Tomcatstarter。我們排除Tomcat的依賴,引入Jetty的依賴即可。

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<exclusions>
		<exclusion>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<groupId>org.springframework.boot</groupId>
		</exclusion>
	</exclusions>
</dependency>

<dependency>
	<artifactId>spring-boot-starter-Jetty</artifactId>
	<groupId>org.springframework.boot</groupId>
</dependency>

四、嵌入式 Servlet容器自動配置原理

【1】EmbeddedServletContainerAutoConfiguration類主要用來自動配置嵌入式的Servlet容器。

@AutoConfigureOrder(-2147483648)
@Configuration
@ConditionalOnWebApplication
 //導(dǎo)入BeanPostProcessorsRegistrar:后置處理器:在bean初始化前后,執(zhí)行(剛創(chuàng)建完對象,還沒屬性賦值)初始化工作.
 //給容器中導(dǎo)入一些組件,導(dǎo)入了embeddedServletContainerCustomizerBeanPostProcessor
@Import({EmbeddedServletContainerAutoConfiguration.BeanPostProcessorsRegistrar.class})
public class EmbeddedServletContainerAutoConfiguration {
    @Configuration
    @ConditionalOnClass({Servlet.class, Tomcat.class})//判斷當(dāng)前Servlet中是否引入的Tomcat依賴
    @ConditionalOnMissingBean(
        value = {EmbeddedServletContainerFactory.class},
        search = SearchStrategy.CURRENT
    )//判斷當(dāng)前容器中,沒有用戶自定義的EmbeddedServletContainerFactory嵌入式的Servlet容器工廠,
    //作用:創(chuàng)建嵌入式的servlet容器。
    public static class EmbeddedTomcat {
        public EmbeddedTomcat() {
        }

        @Bean
        public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
            return new TomcatEmbeddedServletContainerFactory();
        }
    }

    @Configuration
    @ConditionalOnClass({Servlet.class, Undertow.class, SslClientAuthMode.class})
    @ConditionalOnMissingBean(
        value = {EmbeddedServletContainerFactory.class},
        search = SearchStrategy.CURRENT
    )
    public static class EmbeddedUndertow {
        public EmbeddedUndertow() {
        }

        @Bean
        public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory() {
            return new UndertowEmbeddedServletContainerFactory();
        }
    }

    @Configuration
    @ConditionalOnClass({Servlet.class, Server.class, Loader.class, WebAppContext.class})
    @ConditionalOnMissingBean(
        value = {EmbeddedServletContainerFactory.class},
        search = SearchStrategy.CURRENT
    )
    public static class EmbeddedJetty {
        public EmbeddedJetty() {
        }

        @Bean
        public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
            return new JettyEmbeddedServletContainerFactory();
        }
    }
}

【2】嵌入式的容器工廠:EmbeddedServletContainerFactory,用來創(chuàng)建嵌入式的Servlet容器。

public interface EmbeddedServletContainerFactory {
     //獲取嵌入式的Servlet容器
     EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... var1); 
}

? SpringBoot 再帶了三種嵌入式的容器工廠,如下:

【3】EmbeddedServletContainer:嵌入式的容器,SpringBoot 為我們提供了三種不同的嵌入式容器,與工廠相互對應(yīng),如下:

【4】我們進入工廠類 TomcatEmbeddedServletContainerFactory發(fā)現(xiàn),其實也是創(chuàng)建一個 Tomcat并配置其基本屬性。

public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {
	//創(chuàng)建Tomcat
	Tomcat tomcat = new Tomcat();

	//配置Tomcat的基本環(huán)境
	File baseDir = this.baseDirectory != null?this.baseDirectory:this.createTempDir("tomcat");
	tomcat.setBaseDir(baseDir.getAbsolutePath());
	Connector connector = new Connector(this.protocol);
	tomcat.getService().addConnector(connector);
	this.customizeConnector(connector);
	tomcat.setConnector(connector);
	tomcat.getHost().setAutoDeploy(false);
	this.configureEngine(tomcat.getEngine());
	Iterator var5 = this.additionalTomcatConnectors.iterator();

	while(var5.hasNext()) {
		Connector additionalConnector = (Connector)var5.next();
		tomcat.getService().addConnector(additionalConnector);
	}

	this.prepareContext(tomcat.getHost(), initializers);
	//將配置好的Tomcat傳入,并啟動Tomcat,Tomcat.start()
	return this.getTomcatEmbeddedServletContainer(tomcat);
}

【5】用戶自定義的Servlet容器配置類和SpringBoot默認的ServerProperties配置類,都實現(xiàn)了EmbeddedServletContainerCustomizer接口。到底是怎么實現(xiàn)的哪?其實是SpringBoot自動配置類中引入了后置處理器,如下:

//與用戶自定義的Servlet容器實現(xiàn)的接口名很類似,有一定的命名規(guī)則。
embeddedServletContainerCustomizerBeanPostProcessor

? 進入后置處理器類中,重點看如下代碼:

//初始化之前執(zhí)行
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	//如果當(dāng)前初始化的是當(dāng)前ConfigurableEmbeddedServletContainer類型的組件
	if(bean instanceof ConfigurableEmbeddedServletContainer) {
		this.postProcessBeforeInitialization((ConfigurableEmbeddedServletContainer)bean);
	}

	return bean;
}

//上面的postProcessBeforeInitialization方法:
private void postProcessBeforeInitialization(ConfigurableEmbeddedServletContainer bean) {
	Iterator var2 = this.getCustomizers().iterator();

	while(var2.hasNext()) {
		//獲取所有的定制器,調(diào)用每一個定制器的customize方法來給servlet屬性賦值。
		EmbeddedServletContainerCustomizer customizer = (EmbeddedServletContainerCustomizer)var2.next();
		customizer.customize(bean);
	}

private Collection<EmbeddedServletContainerCustomizer> getCustomizers() {
	if(this.customizers == null) {
		//this.beanFactory.xx表示從容器中獲取XXCustomizer自定義類型的組件
		this.customizers = new ArrayList(this.beanFactory.getBeansOfType(EmbeddedServletContainerCustomizer.class, false, false).values());
		Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE);
		this.customizers = Collections.unmodifiableList(this.customizers);
	}

	return this.customizers;
}

整理下步驟:
【1】SpringBoot根據(jù)pom.xml中導(dǎo)入的依賴,給容器中添加其對應(yīng)的嵌入式的服務(wù)容器工廠類,例如默認的Tomcat工廠:EmbeddedServletContainerFactory【TomcatEmbeddedServletContainerFactory】
【2】給容器中某個組件要創(chuàng)建對象就會觸發(fā)后置處理器EmbeddedServletContainerCustomizerBeanPostProcessor,只要是嵌入式的Servlet容器工廠,后置處理器就會工作(默認的ServerProperties也是實現(xiàn)了此類接口的,所以肯定存在相關(guān)配置類)
【3】后置處理器從容器中獲取所有的EmbeddedServletContainerCustomizer,調(diào)用定制器的定制方法。

五、嵌入式Servlet容器啟動原理

根據(jù)上述的流程,我們要研究Servlet容器的啟動原理。其實就是研究什么時候創(chuàng)建嵌入式的容器工廠和何時獲取嵌入式的容器并啟動Tomcat。獲取嵌入式的Servlet容器工廠的過程(在new TomcatEmbeddedServletContainerFactory()時打一個斷電,查看過程):
【1】SpringBoot 應(yīng)用啟動運行 run() 方法。
【2】this.refreshContext(context) 方法:用來初始化 IOC容器,既創(chuàng)建 IOC容器對象并初始化IOC容器中的每一個組件。

protected ConfigurableApplicationContext createApplicationContext() {
	Class<?> contextClass = this.applicationContextClass;
	if(contextClass == null) {
		try {
			//判斷是不是web環(huán)境,是Web環(huán)境引入AnnotationConfigEmbeddedWebApplicationContext,否則引入AnnotationConfigApplicationContext
			contextClass = Class.forName(this.webEnvironment
			?"org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext"
			:"org.springframework.context.annotation.AnnotationConfigApplicationContext");
		} catch (ClassNotFoundException var3) {
			throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
		}
	}

	return (ConfigurableApplicationContext)BeanUtils.instantiate(contextClass);
}

【3】this.refresh(context):刷新剛才創(chuàng)建好的IOC容器。
【4】this.onRefresh()webIoC容器重寫了onRefresh()方法。

protected void onRefresh() {
	super.onRefresh();

	try {
		//重點是創(chuàng)建了嵌入式的Servlet容器
		this.createEmbeddedServletContainer();
	} catch (Throwable var2) {
		throw new ApplicationContextException("Unable to start embedded container", var2);
	}
}

【5】this.createEmbeddedServletContainer()webIOC容器會創(chuàng)建嵌入式的Servlet容器。

private void createEmbeddedServletContainer() {
	EmbeddedServletContainer localContainer = this.embeddedServletContainer;
	ServletContext localServletContext = this.getServletContext();
	if(localContainer == null && localServletContext == null) {
		// 1、獲取嵌入式的Servlet嵌入式的工廠
		EmbeddedServletContainerFactory containerFactory = this.getEmbeddedServletContainerFactory();
		this.embeddedServletContainer = containerFactory.getEmbeddedServletContainer(
				new ServletContextInitializer[]{this.getSelfInitializer()});
	} 
}

【6】獲取嵌入式工廠后,便可從容器中獲取EmbeddedServletContainerFactory的組件tomcatEmbeddedServletContainerFactory來創(chuàng)建Tomcat對象,后置處理器就會觸發(fā)獲取所有的定制器來確定Servlet容器的相關(guān)配置。
【7】通過嵌入式工廠獲取嵌入式容器,如下:

this.embeddedServletContainer = containerFactory.getEmbeddedServletContainer(
                new ServletContextInitializer[]{this.getSelfInitializer()});

● 嵌入式的Servlet容器創(chuàng)建并啟動對象:

public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {
    //創(chuàng)建對象
    Tomcat tomcat = new Tomcat();

    //啟動對象
    this.tomcat.start();

● 先啟動嵌入式的Servlet容器,再將IOC容器中剩下沒有創(chuàng)建的對象進行初始化,如下:

    this.onRefresh();
    //啟動完嵌入式容器后,后續(xù)還有其他對象的初始化工作
    this.registerListeners();
    this.finishBeanFactoryInitialization(beanFactory);
    this.finishRefresh();
} catch (BeansException var9) {

六、使用外置的Servlet容器

嵌入式Servlet容器的缺點: 默認不支持JSP、優(yōu)化和定制比較復(fù)雜。外置Servlet容器:安裝外部的Tomcat,步驟如下:

1)、必須創(chuàng)建一個war項目,需要手動創(chuàng)建目錄(利用Idea快速創(chuàng)建)如下:

?

2)、將嵌入式的Tomcat指定為provide(Idea創(chuàng)建完后,會自動幫我們完成,但我們需要了解)

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-tomcat</artifactId>
	<scope>provided</scope>
</dependency>

3)、需要編寫一個SpringBootServletInitializer的子類,并調(diào)用configure方法:

public class ServletInitializer extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(SpringBootWebApplication.class);
	}
}

4)、配置本地的Tomcat,并啟動Tomcat即可。(此項目運行run()方法是不能啟動項目的):需要設(shè)置名稱和本地Tomcat的路徑即可使用外部Servlet。

七、外置服務(wù)器的使用原理

? jar包:執(zhí)行SpringBoot主類的main方法,啟動并初始化IOC容器且創(chuàng)建嵌入式的Servlet容器。
? war包:啟動服務(wù)器后調(diào)用SpringBootServletInitializer中的configure()方法,加載我們的SpringBoot應(yīng)用并啟動。

Servlet3.0規(guī)則:
 1)、服務(wù)器啟動后,會創(chuàng)建當(dāng)前web應(yīng)用中包含的每個jar內(nèi)的ServletContainerInitializer實例。
 2)、ServletContainerInitializer的實現(xiàn)放在jar包的META-INF/services文件夾下(javax.servlet.ServletContainerInitializer:內(nèi)容就是ServletContainerInitializer的全類名)
 3)、可以使用@handlesTypes注解,在應(yīng)用啟動時加載我們需要的類。

流程: 1)、啟動Tomcat后,獲取servlet.ServletContainerInitializer文件如下:其中的內(nèi)容同下:

在這里插入圖片描述

#文件中的內(nèi)容
org.springframework.web.SpringServletContainerInitializer

 2)、進入SpringServletContainerInitializer發(fā)現(xiàn)此類將@HandlesTypes({WebApplicationInitializer.class})標(biāo)注的所有這個類型的類都傳入到onStartup方法中的Set<Class<?>>,并為這些類創(chuàng)建實例。

@HandlesTypes({WebApplicationInitializer.class})
public class SpringServletContainerInitializer implements ServletContainerInitializer {
    //onStartup方法,用來實例化感興趣的對象
    public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
        if(webAppInitializerClasses != null) {
            var4 = webAppInitializerClasses.iterator();

            while(var4.hasNext()) {
                Class<?> waiClass = (Class)var4.next();
                if(!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
                    try {
                            //實例化
                       initializers.add((WebApplicationInitializer)waiClass.newInstance());
                    } catch (Throwable var7) {
                        throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);
                    }
                }
            }
        }

 3)、每一個WebApplicationInitializer都調(diào)用自己的onStartup()方法。

while(var4.hasNext()) {
	  WebApplicationInitializer initializer = (WebApplicationInitializer)var4.next();
	  //onStartup()方法
	  initializer.onStartup(servletContext);
 }

 4)、WebApplicationInitializer只是一個接口,其實現(xiàn)類主要有以下三個:SpringBootServletInitalizer正是SpringBoot給我們創(chuàng)建好的啟動類,會被創(chuàng)建對象,并啟動自身的onStartup()方法。

 5)、執(zhí)行onStartup()方法時,會調(diào)用createRootApplicationContext()方法來創(chuàng)建容器

public void onStartup(ServletContext servletContext) throws ServletException {
        this.logger = LogFactory.getLog(this.getClass());
        //創(chuàng)建容器
        WebApplicationContext rootAppContext = this.createRootApplicationContext(servletContext);
        if(rootAppContext != null) {
            servletContext.addListener(new ContextLoaderListener(rootAppContext) {
                public void contextInitialized(ServletContextEvent event) {
                }
            });

    //容器的具體調(diào)用實現(xiàn)
    protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) {
        //創(chuàng)建Spring應(yīng)用的構(gòu)建器
        SpringApplicationBuilder builder = this.createSpringApplicationBuilder();
        //設(shè)置主類
        builder.main(this.getClass());
        //創(chuàng)建一些環(huán)境
        ApplicationContext parent = this.getExistingRootWebApplicationContext(servletContext);
        if(parent != null) {
            this.logger.info("Root context already created (using as parent).");
            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, (Object)null);
            builder.initializers(new ApplicationContextInitializer[]{new ParentContextApplicationContextInitializer(parent)});
        }

        builder.initializers(new ApplicationContextInitializer[]{new ServletContextApplicationContextInitializer(servletContext)});
        builder.contextClass(AnnotationConfigServletWebServerApplicationContext.class);

        //重要:子類中重寫了此方法,子類出入了應(yīng)用的主程序類
        builder = this.configure(builder);
        builder.listeners(new ApplicationListener[]{new SpringBootServletInitializer.WebEnvironmentPropertySourceInitializer(servletContext, null)});
        //使用build()創(chuàng)建一個Spring應(yīng)用
        SpringApplication application = builder.build();
        if(application.getAllSources().isEmpty() && AnnotationUtils.findAnnotation(this.getClass(), Configuration.class) != null) {
            application.addPrimarySources(Collections.singleton(this.getClass()));
        }

        Assert.state(!application.getAllSources().isEmpty(), "No SpringApplication sources have been defined. Either override the configure method or add an @Configuration annotation");
        if(this.registerErrorPageFilter) {
            application.addPrimarySources(Collections.singleton(ErrorPageFilterConfiguration.class));
        }
        //啟動應(yīng)用
        return this.run(application);
    }

 6)、執(zhí)行應(yīng)用的run()方法,來啟動Spring應(yīng)用并創(chuàng)建IOC容器。

public ConfigurableApplicationContext run(String... args) {
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	ConfigurableApplicationContext context = null;
	Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
	this.configureHeadlessProperty();
	SpringApplicationRunListeners listeners = this.getRunListeners(args);
	listeners.starting();

	Collection exceptionReporters;
	try {
		ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
		ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
		this.configureIgnoreBeanInfo(environment);
		Banner printedBanner = this.printBanner(environment);
		context = this.createApplicationContext();
		exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, new Object[]{context});
		this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);

		//刷新IOC容器
		this.refreshContext(context);
		this.afterRefresh(context, applicationArguments);
		stopWatch.stop();
		if(this.logStartupInfo) {
			(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
		}

		listeners.started(context);
		this.callRunners(context, applicationArguments);
	} catch (Throwable var10) {
		this.handleRunFailure(context, var10, exceptionReporters, listeners);
		throw new IllegalStateException(var10);
	}

	try {
		listeners.running(context);
		return context;
	} catch (Throwable var9) {
		this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
		throw new IllegalStateException(var9);
	}
}

到此這篇關(guān)于SpringBoot實現(xiàn)嵌入式 Servlet容器的文章就介紹到這了,更多相關(guān)SpringBoot 嵌入式 Servlet容器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Java用POI解析excel并獲取所有單元格數(shù)據(jù)的實例

    Java用POI解析excel并獲取所有單元格數(shù)據(jù)的實例

    下面小編就為大家?guī)硪黄狫ava用POI解析excel并獲取所有單元格數(shù)據(jù)的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • 利用棧使用簡易計算器(Java實現(xiàn))

    利用棧使用簡易計算器(Java實現(xiàn))

    這篇文章主要為大家詳細介紹了Java利用棧實現(xiàn)簡易計算器,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • JAVA面試題之Forward與Redirect的區(qū)別詳解

    JAVA面試題之Forward與Redirect的區(qū)別詳解

    這篇文章主要給大家介紹了在JAVA面試中可能遇到會遇到的一道題,就是java中Forward與Redirect兩者之前的區(qū)別,文中介紹的非常詳細,對大家具有一定參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • Java ThreadLocal的使用詳解

    Java ThreadLocal的使用詳解

    ThreadLocal是線程私有的局部變量存儲容器,可以理解成每個線程都有自己專屬的存儲容器,用來存儲線程私有變量。ThreadLocal 在日常開發(fā)框架中應(yīng)用廣泛,但用不好也會出現(xiàn)各種問題,本文就此講解一下。
    2021-05-05
  • Java全面解析IO流相關(guān)知識

    Java全面解析IO流相關(guān)知識

    這篇文章主要介紹了IO流相關(guān)知識,包括File,字節(jié)流,字符流,特殊操作流(標(biāo)準(zhǔn)輸入流,標(biāo)準(zhǔn)輸出流,對象序列化與反序列化,properties與IO流結(jié)合)相關(guān)知識的總結(jié)
    2021-08-08
  • log4j配置失效日志中打印Debug信息問題

    log4j配置失效日志中打印Debug信息問題

    這篇文章主要介紹了log4j配置失效日志中打印Debug信息問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Spring Cloud Hystrix線程池不足的解決方法

    Spring Cloud Hystrix線程池不足的解決方法

    這篇文章主要介紹了Spring Cloud Hystrix線程池不足的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 2種Java刪除ArrayList中的重復(fù)元素的方法

    2種Java刪除ArrayList中的重復(fù)元素的方法

    這篇文章主要介紹了2種Java刪除ArrayList中的重復(fù)元素的方法,感興趣的朋友可以參考下
    2015-08-08
  • SpringBoot整合Mysql和Redis的詳細過程

    SpringBoot整合Mysql和Redis的詳細過程

    這篇文章主要介紹了SpringBoot整合Mysql和Redis的示例代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • Spring框架七大模塊簡單介紹

    Spring框架七大模塊簡單介紹

    這篇文章主要介紹了Spring框架七大模塊簡單介紹,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11

最新評論