iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >springboot中如何利用Tomcat容器实现自启动
  • 845
分享到

springboot中如何利用Tomcat容器实现自启动

2023-06-08 04:06:27 845人浏览 泡泡鱼
摘要

这篇“SpringBoot中如何利用Tomcat容器实现自启动”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springbo

这篇“SpringBoot中如何利用Tomcat容器实现自启动”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springboot中如何利用Tomcat容器实现自启动”文章吧。

一、Spring通过注解导入Bean大体可分为四种方式,我们主要来说以下Import的两种实现方法:

1、通过实现ImportSerlector接口,实现Bean加载:

public class TestServiceImpl { public void testImpl() { System.out.println("我是通过importSelector导入进来的service"); }}public class TestService implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{"com.ycdhz.service.TestServiceImpl"}; }}@Configuration@Import(value = {TestService.class})public class TestConfig {}public class TestController { @Autowired private TestServiceImpl testServiceImpl;  @RequestMapping("testImpl") public String testTuling() { testServiceImpl.testImpl(); return "Ok"; }}

2、 通过实现ImportSerlector接口,实现Bean加载:

public class TestService { public TestService() { System.out.println("我是通过ImportBeanDefinitionReGIStrar导入进来的组件"); }}public class TestImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importinGClaSSMetadata, BeanDefinitionRegistry registry) { //定义一个BeanDefinition RootBeanDefinition beanDefinition = new RootBeanDefinition(TestService.class); //把自定义的bean定义导入到容器中 registry.registerBeanDefinition("testService",beanDefinition); }}@Configuration@Import(TestImportBeanDefinitionRegistrar.class)public class TestConfig {}

二、 Springboot启动过程中会自动装配

我们从spring-boot-autoconfigure-2.0.6.RELEASE.jar下搜索到Tomcat的相关配置,发现有两个自动装配类,分别包含了三个定制器(面向对象的单一职责原则),还有一个工厂类。

springboot中如何利用Tomcat容器实现自启动

2.1、TomcatWEBServerFactoryCustomizer:定制Servlet和Reactive服务器通用的Tomcat特定功能。

public class TomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory>, Ordered { @Override public void customize(ConfigurableTomcatWebServerFactory factory) { ServerProperties properties = this.serverProperties; ServerProperties.Tomcat tomcatProperties = properties.getTomcat(); PropertyMapper propertyMapper = PropertyMapper.get(); propertyMapper.from(tomcatProperties::getBasedir).whenNonNull() .to(factory::setBaseDirectory); propertyMapper.from(tomcatProperties::getBackgroundProcessorDelay).whenNonNull() .as(Duration::getSeconds).as(Long::intValue) .to(factory::setBackgroundProcessorDelay); customizeRemoteIpValve(factory); propertyMapper.from(tomcatProperties::getMaxThreads).when(this::isPositive) .to((maxThreads) -> customizeMaxThreads(factory,  tomcatProperties.getMaxThreads())); propertyMapper.from(tomcatProperties::getMinSpareThreads).when(this::isPositive) .to((minSpareThreads) -> customizeMinThreads(factory, minSpareThreads)); propertyMapper.from(() -> determineMaxHttpHeaderSize()).when(this::isPositive) .to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory,  maxHttpHeaderSize)); propertyMapper.from(tomcatProperties::getMaxHttpPostSize) .when((maxHttpPostSize) -> maxHttpPostSize != 0) .to((maxHttpPostSize) -> customizeMaxHttpPostSize(factory,  maxHttpPostSize)); propertyMapper.from(tomcatProperties::getAccesslog) .when(ServerProperties.Tomcat.Accesslog::isEnabled) .to((enabled) -> customizeAccessLog(factory)); propertyMapper.from(tomcatProperties::getUriEncoding).whenNonNull() .to(factory::setUriEncoding); propertyMapper.from(properties::getConnectionTimeout).whenNonNull() .to((connectionTimeout) -> customizeConnectionTimeout(factory,  connectionTimeout)); propertyMapper.from(tomcatProperties::getMaxConnections).when(this::isPositive) .to((maxConnections) -> customizeMaxConnections(factory, maxConnections)); propertyMapper.from(tomcatProperties::getAcceptCount).when(this::isPositive) .to((acceptCount) -> customizeAcceptCount(factory, acceptCount)); customizeStaticResources(factory); customizeErrorReportValve(properties.getError(), factory); }}

2.2、ServletWebServerFactoryCustomizer:WebServerFactoryCustomizer 将ServerProperties属性应用于Tomcat web服务器

public class ServletWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered { private final ServerProperties serverProperties; public ServletWebServerFactoryCustomizer(ServerProperties serverProperties) { this.serverProperties = serverProperties; } @Override public int getOrder() { return 0; } @Override public void customize(ConfigurableServletWebServerFactory factory) { PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); map.from(this.serverProperties::getPort).to(factory::setPort); map.from(this.serverProperties::getAddress).to(factory::setAddress); map.from(this.serverProperties.getServlet()::getContextPath) .to(factory::setContextPath); map.from(this.serverProperties.getServlet()::getApplicationDisplayName) .to(factory::setDisplayName); map.from(this.serverProperties.getServlet()::getSession).to(factory::setSession); map.from(this.serverProperties::getSsl).to(factory::setSsl); map.from(this.serverProperties.getServlet()::getjsp).to(factory::setJsp); map.from(this.serverProperties::getCompression).to(factory::setCompression); map.from(this.serverProperties::getHttp2).to(factory::setHttp2); map.from(this.serverProperties::getServerHeader).to(factory::setServerHeader); map.from(this.serverProperties.getServlet()::getContextParameters) .to(factory::setInitParameters); }}

2.3、ServletWebServerFactoryCustomizer :WebServerFactoryCustomizer 将ServerProperties属性应用于Tomcat web服务器。

public class TomcatServletWebServerFactoryCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>, Ordered { private final ServerProperties serverProperties; public TomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) { this.serverProperties = serverProperties; } @Override public void customize(TomcatServletWebServerFactory factory) { ServerProperties.Tomcat tomcatProperties = this.serverProperties.getTomcat(); if (!ObjectUtils.isEmpty(tomcatProperties.getAdditionalTldSkipPatterns())) { factory.getTldSkipPatterns()  .addAll(tomcatProperties.getAdditionalTldSkipPatterns()); } if (tomcatProperties.getRedirectContextRoot() != null) { customizeRedirectContextRoot(factory,  tomcatProperties.getRedirectContextRoot()); } if (tomcatProperties.getUseRelativeRedirects() != null) { customizeUseRelativeRedirects(factory,  tomcatProperties.getUseRelativeRedirects()); } }}

三、有了TomcatServletWebServerFactory,相当于有了Spring加载的入口

通过AbstractApplicationContext#onReFresh()在ioc 容器中的带动tomcat启动,然后在接着执行 ioc容器的其他步骤。

我们通过断点可以观察Tomcat加载的整个生命周期,以及三个定制器的加载过程。

springboot中如何利用Tomcat容器实现自启动

@Overridepublic 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); //创建Tomcat引擎 configureEngine(tomcat.getEngine()); for (Connector additionalConnector : this.additionalTomcatConnectors) { tomcat.getService().addConnector(additionalConnector); } //刷新上下文 prepareContext(tomcat.getHost(), initializers); //准备启动 return getTomcatWebServer(tomcat);}
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) { stopSilently(); throw new WebServerException("Unable to start embedded Tomcat", ex); } }}

备注: 在这个过程中我们需要了解Bean的生命周期,Tomcat的三个定制器均在BeanPostProcessorsRegistrar(Bean后置处理器)过程中加载;

  构造方法-->Bean后置处理器Before-->InitializingBean-->init-method-->Bean后置处理器After

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean  org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //构造方法 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Initialize the bean instance. ...... return exposedObject;}protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //Bean后置处理器Before wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //Bean后置处理器After wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean;}

以上就是关于“springboot中如何利用Tomcat容器实现自启动”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。

--结束END--

本文标题: springboot中如何利用Tomcat容器实现自启动

本文链接: https://www.lsjlt.com/news/251858.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • springboot中如何利用Tomcat容器实现自启动
    这篇“springboot中如何利用Tomcat容器实现自启动”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springbo...
    99+
    2023-06-08
  • SpringBoot如何实现Tomcat自动配置
    目录准备工作 启动 接着往下看 目录 准备工作 我们知道SpringBoot的自动装配的秘密在 org.springframework.boot.autoconfigure 包下的...
    99+
    2024-04-02
  • 如何在SpringBoot中启动tomcat
    如何在SpringBoot中启动tomcat?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。springboot是什么springboot一种全新的编程规范,其设计目的是用来...
    99+
    2023-06-14
  • Tomcat中SpringBoot应用无法启动如何解决
    Tomcat中SpringBoot应用无法启动如何解决?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。问题描述我修改pom.xml将打包方式改成war<packagin...
    99+
    2023-05-31
    springboot omc tomcat
  • springboot 自定义启动器的实现
    目录创建自定义启动器0、项目总览1、创建项目,引入依赖2、创建属性配置类3、创建自动配置类4、创建自动配置属性文件使用自定义启动器1、springboot_01 项目引入自定义启动器...
    99+
    2023-02-01
    springboot 自定义启动器 springboot  启动器
  • springboot 项目容器启动后如何自动执行指定方法
    目录springboot 项目容器启动后自动执行指定springboot 容器及启动过程问题1:为什么要启动父子两个容器?问题2:在什么时候启动父容器?问题3:父容器和子容器的区别?...
    99+
    2024-04-02
  • SpringBoot自动配置如何实现
    这篇文章主要介绍“SpringBoot自动配置如何实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringBoot自动配置如何实现”文章能帮助大家解决问题。springboot如何实现在之前的...
    99+
    2023-06-30
  • SpringBoot自定义starter启动器的实现思路
    目录一.引言二. 需求说明三. 设计思路四. 实现步骤1. Step1 业务定义2. Step2 自动配置2.1 HelloService类2.2 HelloProperties类2...
    99+
    2022-11-13
    SpringBoot自定义starter启动器 SpringBoot自定义starter
  • kubernetes中如何实现Pod自动扩容与缩容
    小编给大家分享一下kubernetes中如何实现Pod自动扩容与缩容,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一:简介Kubernetes通过HPA控制器,用于实现基本CPU使用率进行自动Pod扩容和缩容的功能。HAP...
    99+
    2023-06-04
  • 如何在 Docker 容器中自动重启 golang 应用程序?
    小伙伴们对Golang编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《如何在 Docker 容器中自动重启 golang 应用程序?》,就很适合你,本篇文章讲解的知识点主要包括。在之后的文章...
    99+
    2024-04-04
  • 如何设置docker开机自启动,并设置容器自动重启
    目录设置docker开机自启动,并设置容器自动重启设置docker开机启动设置容器自动重启docker常用命令 设置docker、容器 自动启动启动docker 设置docker 自...
    99+
    2023-02-14
    docker开机自启动 容器自动重启 docker自启动
  • SpringBoot实现自定义启动器的示例详解
    目录开发步骤测试自定义启动器启动器支持多Druid和C3P0开发步骤 1.创建启动器项目 添加启动器相关依赖创建属性配置类创建自动配置类编写自动配置文件(spring.factori...
    99+
    2023-01-12
    SpringBoot自定义启动器 SpringBoot 启动器
  • SpringBoot的jar包如何启动的实现
    目录一、简介二、jar包的内部结构三、加载过程1.使用到的一些类2.过程分析四、总结一、简介 ​ 使用过SprongBoot打过jar包的都应该知道,目标文件一般都会生成两个文件,一...
    99+
    2024-04-02
  • 使用Dockerfile实现容器内部服务随容器自启动的方法
    目录1 Docker下载python2 搭建flask服务2.1 创建flask脚本2.2 创建gunicorn启动脚本3 制作镜像3.1 将mypython容器制作成镜像3.2 D...
    99+
    2024-04-02
  • springBoot项目如何实现启动多个实例
    springBoot项目启动多个实例 今天碰到一个需求是,将一个服务提供者启动两个实例,一个实例对外,一个实例对内,对内价格有折扣,两个实例通过指定不停的profile来区分,要求是...
    99+
    2024-04-02
  • 利用Redis如何实现自动补全功能
    忘了redis从哪个版本开启,能够根据输入的部分命令前缀给出提示,即自动补全。接下来笔者介绍基于redis实现这个很酷的功能。 about sorted set 假设结果中有mara,marabel,ma...
    99+
    2024-04-02
  • springboot中怎么利用logback启动报警报错如何解决
    本篇文章为大家展示了springboot中怎么利用logback启动报警报错如何解决,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。springboot logback启动报警报错报错信息如下:16:...
    99+
    2023-06-20
  • 如何使用shell实现自动重启服务
    小编给大家分享一下如何使用shell实现自动重启服务,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!代码如下:#!/bin/bash if [ ! -f /tmp/...
    99+
    2023-06-09
  • 云服务器启动tomcat没用如何解决
    启动云服务器上的Tomcat可能会遇到多种问题。以下是一些常见问题及其解决方法:1. 端口冲突:检查服务器上的其他应用程序是否在使用...
    99+
    2023-09-16
    云服务器 tomcat
  • SpringBoot中利用AOP和拦截器实现自定义注解
    目录前言Spring实现自定义注解1.引入相关依赖2.相关类Java实现自定义注解通过Cglib实现通过JDk动态代理实现Cglib和JDK动态代理的区别写在最后前言 最近遇到了这样...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作