Springboot Web应用中服务器配置参数ServerProperties的加载

来源:互联网 发布:香港淘宝怎么注册 编辑:程序博客网 时间:2024/06/04 20:46

概述

Springboot配置文件中以server开头的项表示服务器的配置参数,这一点从字面意义即可直观理解,这些参数,包括端口,路径设置,SSL配置参数等等。具体有哪些参数,从源代码的角度上,可以参考类ServerProperties的定义,它位于包 org.springframework.boot.autoconfigure.web 中。

服务器配置参数的加载,Springboot应用中是通过其自动配置机制来实现的,下面就具体分析其过程。

自动配置定义服务器配置参数加载工具

EmbeddedServletContainerAutoConfiguration注册bean EmbeddedServletContainerCustomizerBeanPostProcessor

EmbeddedServletContainerAutoConfiguration是Springboot的自动配置类,位于包

package org.springframework.boot.autoconfigure.web

这个配置类以内部类的形式定义了一个ImportBeanDefinitionRegistrar并通过@Import注解导入,而该导入会引起向容器注册一个Bean embeddedServletContainerCustomizerBeanPostProcessor。

// 该代码引用略去与本主题无关部分@Configuration@ConditionalOnWebApplication@Import(BeanPostProcessorsRegistrar.class)//内部类BeanPostProcessorsRegistrar导入public class EmbeddedServletContainerAutoConfiguration {    // 内部类BeanPostProcessorsRegistrar定义    public static class BeanPostProcessorsRegistrar            implements ImportBeanDefinitionRegistrar, BeanFactoryAware {@Override        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,                BeanDefinitionRegistry registry) {            if (this.beanFactory == null) {                return;            }            // 注册bean embeddedServletContainerCustomizerBeanPostProcessor,            // 对应类 EmbeddedServletContainerCustomizerBeanPostProcessor.class            registerSyntheticBeanIfMissing(registry,                    "embeddedServletContainerCustomizerBeanPostProcessor",                    EmbeddedServletContainerCustomizerBeanPostProcessor.class);        }                       }}

关于上面ImportBeanDefinitionRegistrar的执行时机,可以参考 :
ConfigurationClassBeanDefinitionReader 是如何工作的 ?

Bean embeddedServletContainerCustomizerBeanPostProcessor对应类为
EmbeddedServletContainerCustomizerBeanPostProcessor,该类实现了 BeanPostProcessor, BeanFactoryAware 两个接口。

该bean embeddedServletContainerCustomizerBeanPostProcessor的用途是把Bean容器中注册的所有EmbeddedServletContainerCustomizer bean应用到ConfigurableEmbeddedServletContainer。而在基于tomcat的Springboot Web应用中,这里会是一个TomcatEmbeddedServletContainerFactory 。

ServerPropertiesAutoConfiguration定义服务器配置参数加载工具Bean serverProperties

ServerPropertiesAutoConfiguration是Springboot的另外一个自动配置类,位于包

package org.springframework.boot.autoconfigure.web

它定义了bean serverProperties,对应实现类ServerProperties,这是负责加载服务器配置参数的工具类。

// 该代码引用略去与本主题无关部分@Configuration@EnableConfigurationProperties@ConditionalOnWebApplicationpublic class ServerPropertiesAutoConfiguration {    // 定义加载服务器配置参数的工具bean    @Bean    @ConditionalOnMissingBean(search = SearchStrategy.CURRENT)    public ServerProperties serverProperties() {        return new ServerProperties();    }

ServerProperties读取服务器配置参数

ServerProperties是springboot的自动配置autoconfigure工具,位于包

org.springframework.boot.autoconfigure.web

该类用于提供服务器的端口,路径,SSL等参数设置,它实现了接口EmbeddedServletContainerCustomizer,是专门设计给EmbeddedServletContainerCustomizerBeanPostProcessor用来定制EmbeddedServletContainerFactory实例的。

ServerProperties在容器启动时会被作为bean定义注册到容器,在容器启动过程中应用EmbeddedServletContainerCustomizerBeanPostProcessor的阶段,ServerProperties bean会被实例化,此时配置文件会被该bean读取。

具体的执行入口点如下 :

SpringApplication.run() => refreshContext()  => EmbeddedWebApplicationContext.refresh()  => onRefresh()    => createEmbeddedServletContainer()  => getEmbeddedServletContainerFactory()    => AbstractBeanFactory.getBean("tomcatEmbeddedServletContainerFactory")    => doGetBean()    => DefaultSingletonBeanRegistry.getSingleton()        => AbstractAutowireCapableBeanFactory.doCreateBean()    => initializeBean() // 此时Bean已经实例化,并且已经填充能从容器中获得的属性    => applyBeanPostProcessorsBeforeInitialization()// 此时被已经调用aware方法

上面的方法applyBeanPostProcessorsBeforeInitialization()会在当前bean上面尝试应用所有注册到容器的BeanPostProcessor。

// 实现在 AbstractAutowireCapableBeanFactory 中// 对existingBean应用所有BeanPostProcessor ,从以下逻辑可以看出,此时尚不区分某个// BeanPostProcessor对bean existingBean是否可以真正执行,这个判断逻辑,交给具体的// BeanPostProcessor实现来完成@Override    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)            throws BeansException {        Object result = existingBean;        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {            result = beanProcessor.postProcessBeforeInitialization(result, beanName);            if (result == null) {                return result;            }        }        return result;    }

BeanPostProcessor bean EmbeddedServletContainerCustomizerBeanPostProcessor 发现bean tomcatEmbeddedServletContainerFactory是其目标应用对象,所以就会将自己的方法postProcessBeforeInitialization()针对其执行:

    // 类EmbeddedServletContainerCustomizerBeanPostProcessor的方法实现    // 类EmbeddedServletContainerCustomizerBeanPostProcessor实现了BeanPostProcessor接口    @Override    public Object postProcessBeforeInitialization(Object bean, String beanName)            throws BeansException {        if (bean instanceof ConfigurableEmbeddedServletContainer) {            postProcessBeforeInitialization((ConfigurableEmbeddedServletContainer) bean);        }        return bean;    }    // 将所有的customizer应用到目标bean上    // 从上面的分析已经知道ServerProperties就是一个    // EmbeddedServletContainerCustomizer,所以在这个方法执行时,bean serverProperties    // 会将服务器配置参数设置到目标内置servlet容器    private void postProcessBeforeInitialization(            ConfigurableEmbeddedServletContainer bean) {        for (EmbeddedServletContainerCustomizer customizer : getCustomizers()) {            customizer.customize(bean);        }    }       // 所有的customizer是容器中类别为EmbeddedServletContainerCustomizer的bean定义,    // 这里获取并实例化它们,从上面的分析已经知道ServerProperties是一个    // EmbeddedServletContainerCustomizer,所以在下面方法执行时,bean ServerProperties就会被    // 实例化,相应的服务器配置参数会被加载进来    private Collection<EmbeddedServletContainerCustomizer> getCustomizers() {        if (this.customizers == null) {            // Look up does not include the parent context            this.customizers = new ArrayList<EmbeddedServletContainerCustomizer>(                    this.beanFactory                            .getBeansOfType(EmbeddedServletContainerCustomizer.class,                                    false, false)                            .values());            Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE);            this.customizers = Collections.unmodifiableList(this.customizers);        }        return this.customizers;    }   
阅读全文
0 0