springboot情操陶冶-web配置(一)

承接前文springboot情操陶冶[email protected]注解解析,在前文讲解的基础上依次看下web方面的相关配置

环境包依赖

pom.xml文件中引入web依赖,炒鸡简单,如下

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

上述的三行依赖代码便完成了对web环境的配置,此时可以直接运行main()方法

package com.example.demospringbootweb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoSpringbootWebApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoSpringbootWebApplication.class, args);
    }
}

默认服务是挂载在Tomcat容器中,端口为8080。所以可以通过该链接直接访问http://127.0.0.1:8080便可得到以下页面(未配置index页面的效果)

应用端口和上下文配置

本文将在上文的基础山讲解端口和上下文路径的具体配置以及解析。现附上简单的步骤操作



创建application-servlet.properties文件,专门用于配置应用服务

#server application config
server.port=9001
server.servlet.context-path=/demoWeb


application.properties文件中指定激活的profile,用于使上述文件生效

spring.profiles.active=servlet


为了使界面变得稍微友好,引入index.html文件,放置于static目录下,如下



继续运行对应的main()函数,便可访问http://127.0.0.1:9001/demoWeb,得到以下结果

源码剖析

关于Tomcat等容器的配置,springboot采用了EmbeddedWebServerFactoryCustomizerAutoConfigurationServletWebServerFactoryAutoConfiguration两个类便完成了。笔者针对这两个类进行简单的分析

EmbeddedWebServerFactoryCustomizerAutoConfiguration

直接查看其内部源码,如下

@Configuration
@EnableConfigurationProperties(ServerProperties.class)
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {
}

主要是引入了ServerProperties配置类,而其是读取spring上下文环境中的以server为开头的属性,简单的看下

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
    @ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })
    public static class TomcatWebServerFactoryCustomizerConfiguration {

        @Bean
        public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(
                Environment environment, ServerProperties serverProperties) {
            return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
        }

    }

    /**
     * Nested configuration if Jetty is being used.
     */
    @Configuration
    @ConditionalOnClass({ Server.class, Loader.class, WebAppContext.class })
    public static class JettyWebServerFactoryCustomizerConfiguration {

        @Bean
        public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(
                Environment environment, ServerProperties serverProperties) {
            return new JettyWebServerFactoryCustomizer(environment, serverProperties);
        }

    }

    /**
     * Nested configuration if Undertow is being used.
     */
    @Configuration
    @ConditionalOnClass({ Undertow.class, SslClientAuthMode.class })
    public static class UndertowWebServerFactoryCustomizerConfiguration {

        @Bean
        public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(
                Environment environment, ServerProperties serverProperties) {
            return new UndertowWebServerFactoryCustomizer(environment, serverProperties);
        }

    }
}

样例中的port/servlet.context-path便是保存在ServerProperties对象中的,具体其内部的属性本文就不展开了,读者可自行去阅读源码。
由上述的简单代码得知该自动配置类主要根据classpath环境创建不同的应用容器,默认springboot集成的都是tomcat。我们此处只关注下TomcatWebServerFactoryCustomizer类,下文中会有所提及

ServletWebServerFactoryAutoConfiguration

具体的ServletWebServer容器配置是通过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 {
}

要想本自动配置生效则必须classpath环境中存在ServletRequest.class等servlet环境依赖类,这一般引入开头的starter-web版块便基本满足了



创建webServerFactory类

    @Bean
    public 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);
    }

这两个bean类和上文中的TomcatWebServerFactoryCustomizer很相似,但仔细阅读源码之后便发现其实这只是tomcat配置的分工处理,小结如下

  • TomcatWebServerFactoryCustomizer 配置tomcat的主要信息,包含remoteIpValue、connector(最大/最小可接收线程、最大可接收头部大小等等)、uriEncoding、connectionTimeout、maxConnection等属性
  • TomcatServletWebServerFactoryCustomizer 配置tomcat的额外信息,redirectContextRoot(是否在请求根上下文时转发,true则转发路径为/demoWeb/)和useRelativeRedirects(是否使用相对路径)等路径跳转问题处理
  • ServletWebServerFactoryCustomizer 主要配置tomcat的servlet的信息,包含端口、上下文路径、应用名、Session配置、Servlet携带的初始变量等等

通过上述的三个bean类便基本完成了基本的tomcat配置,其都是WebServerFactoryCustomizer接口的实现类,那么是被谁来统一调用以完成上述的配置呢?



1.首先引入了WebServerFactory工厂类,此点可直接看由上述@Import引入的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();
        }

    }

创建了TomcatServletWebServerFactory的tomcat容器,其余的web容器读者可自行分析



2.最后通过beanPostProcessor接口来完成相应的容器初始化
@Import引入的BeanPostProcessorsRegistrar类,注册了webServerFactoryCustomizerBeanPostProcessor类来完成相应的tomcat个性化配置

    // 初始化上述的WebServerFactory对象前操作
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof WebServerFactory) {
            this.postProcessBeforeInitialization((WebServerFactory)bean);
        }

        return bean;
    }

    // 调用所有实现了WebServerFactoryCustomizer接口的对象
    private void postProcessBeforeInitialization(WebServerFactory webServerFactory) {
        ((Callbacks)LambdaSafe.callbacks(WebServerFactoryCustomizer.class, this.getCustomizers(), webServerFactory, new Object[0]).withLogger(WebServerFactoryCustomizerBeanPostProcessor.class)).invoke((customizer) -> {
            customizer.customize(webServerFactory);
        });
    }

    // 查找当前bean工厂中所有类型为WebServerFactoryCustomizer接口对象集合
    private Collection<WebServerFactoryCustomizer<?>> getCustomizers() {
        if (this.customizers == null) {
            this.customizers = new ArrayList(this.getWebServerFactoryCustomizerBeans());
            this.customizers.sort(AnnotationAwareOrderComparator.INSTANCE);
            this.customizers = Collections.unmodifiableList(this.customizers);
        }

        return this.customizers;
    }

    private Collection<WebServerFactoryCustomizer<?>> getWebServerFactoryCustomizerBeans() {
        return this.beanFactory.getBeansOfType(WebServerFactoryCustomizer.class, false, false).values();
    }

具体的解析见上述的代码注释,其实也很简单并一目了然,所以如果用户想在tomcat上再作个性化的需求,可自行实现WebServerFactoryCustomizer接口并注册至bean工厂即可

@Configuration
public MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>{
    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
        // do personal binding
    }
}

小结

本文只讲述tomcat的相关配置,并举例说明了其port/contextPath的应用配置,更多的配置读者可采用springboot实现的带server前缀的配置以及自行实现WebServerFactoryCustomizer接口去实现

原文地址:https://www.cnblogs.com/question-sky/p/9580060.html

时间: 2024-08-30 10:16:15

springboot情操陶冶-web配置(一)的相关文章

springboot情操陶冶[email&#160;protected]注解解析

承接前文springboot情操陶冶[email protected]注解解析,本文将在前文的基础上对@SpringBootApplication注解作下简单的分析 @SpringBootApplication 该注解是springboot最集中的一个注解,也是应用最广泛的注解.官方也多用此注解以启动spring服务,我们看下其中的源码 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inher

springboot情操陶冶[email&#160;protected]和@AutoConfigureAfter注解解析

承接前文springboot情操陶冶[email protected]注解解析,本文将在前文的基础上阐述@AutoConfigureAfter和@Conditional注解的作用与解析 [email protected] 根据单词来理解,其就是条件的意思.在分析之前我们可以看下其内部源码 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @i

springboot情操陶冶-jmx解析

承接前文springboot情操陶冶[email protected]注解解析,近期笔者接触的项目中有使用到了jmx的协议框架,遂在前文的基础上讲解下springboot中是如何整合jmx的 知识储备 JMX:Java Management Extension(Java管理应用扩展),这种机制可以方便的管理.监控正在运行的Java程序.常用于监控管理线程.内存.日志Level.服务重启.系统环境等等. 更多的知识点参考此篇文献:https://blog.csdn.net/u013256816/a

SpringBoot的Web配置

重写全局配置 如果springboot提供的springmvc配置不符合要求,则可以通过一个配置类(标有@Configuration注解的类)加上@EnableWebMvc注解来实现完全自己控制的mvc配置 当你既想保留springboot提供的配置,又想增加自己额外的配置时,可以定义一个配置类并继承WebMvcConfigurationAdapter,无须使用@EnableWebMvc注解 servlet容器配置(servlet容器配置) 如果需要使用代码的方式配置servlet容器,则可以注

SpringBoot系列教程web篇之404、500异常页面配置

接着前面几篇web处理请求的博文,本文将说明,当出现异常的场景下,如404请求url不存在,,403无权,500服务器异常时,我们可以如何处理 原文友链: SpringBoot系列教程web篇之404.500异常页面配置 I. 环境搭建 首先得搭建一个web应用才有可能继续后续的测试,借助SpringBoot搭建一个web应用属于比较简单的活; 创建一个maven项目,pom文件如下 <parent> <groupId>org.springframework.boot</gr

使用idea+springboot+Mybatis搭建web项目

使用idea+springboot+Mybatis搭建web项目 springboot的优势之一就是快速搭建项目,省去了自己导入jar包和配置xml的时间,使用非常方便. 1.创建项目project,然后选择Spring initializr,点击下一步  2.按图示进行勾选,点击下一步,给项目起个名字,点击确定. 3.项目生成有,点击add as maven project,idea 会自动下载jar包,时间比较长  4.项目生成后格式如下图所示:  其中DemoApplication.jav

Spring源码情操陶冶#task:scheduled-tasks解析器

承接前文Spring源码情操陶冶#task:executor解析器,在前文基础上解析我们常用的spring中的定时任务的节点配置.备注:此文建立在spring的4.2.3.RELEASE版本 附例 Spring中的定时任务基本配置样例如下 <!--create schedule thread pool--> <task:scheduler id="baseScheduler" pool-size="5"></task:scheduler

Spring源码情操陶冶-tx:advice解析器

承接Spring源码情操陶冶-自定义节点的解析.本节关于事务进行简单的解析 spring配置文件样例 简单的事务配置,对save/delete开头的方法加事务,get/find开头的设置为不加事务只读模式 <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*"

MyEclipse发布Springboot项目到MyEclipse配置的Tomcat中

MyEclipse发布Springboot项目到MyEclipse配置的Tomcat中步骤一: 右键点击项目名,选择Build Path --> Configure Bulid Path... 步骤二: 找到MyEclipse -- > Deployment Assembly,点击Add... 步骤三: 选中 Java Build Path Entries,点击 Next > 步骤四: 选中 Maven Dependencies,点击 Finish 步骤五: 可以看到maven的包已经被