在了解了Spring Boot的运做原理和主要注解后,如今来简单的分析一个Spring Boot内置的自动配置功能:http的编码配置。java
咱们在常规项目中配置Http编码的时候是在web.xml添加一个filter,如:web
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter>
自动配置要知足两个条件:spring
在前面咱们讲述了类型安全配置,Spring Boot也是基于这一点来实现的,这里的配置类能够在application.properties中直接设置,源码以下:安全
package org.springframework.boot.autoconfigure.web; import java.nio.charset.Charset; import java.util.Locale; import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "spring.http.encoding")// 在application.properties中配置的前缀是spring.http.encoding public class HttpEncodingProperties { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); private Charset charset = DEFAULT_CHARSET; // 默认的编码方式 private Boolean force; private Boolean forceRequest; private Boolean forceResponse; private Map<Locale, Charset> mapping; public Charset getCharset() { return this.charset; } public void setCharset(Charset charset) { this.charset = charset; } public boolean isForce() { return Boolean.TRUE.equals(this.force); } public void setForce(boolean force) { this.force = force; } public boolean isForceRequest() { return Boolean.TRUE.equals(this.forceRequest); } public void setForceRequest(boolean forceRequest) { this.forceRequest = forceRequest; } public boolean isForceResponse() { return Boolean.TRUE.equals(this.forceResponse); } public void setForceResponse(boolean forceResponse) { this.forceResponse = forceResponse; } public Map<Locale, Charset> getMapping() { return this.mapping; } public void setMapping(Map<Locale, Charset> mapping) { this.mapping = mapping; } boolean shouldForce(Type type) { Boolean force = (type == Type.REQUEST ? this.forceRequest : this.forceResponse); if (force == null) { force = this.force; } if (force == null) { force = (type == Type.REQUEST); } return force; } enum Type { REQUEST, RESPONSE } }
经过调用上述配置并根据条件配置CharacterEncodingFilter的Bean,看源码:app
package org.springframework.boot.autoconfigure.web; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.web.HttpEncodingProperties.Type; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.filter.OrderedCharacterEncodingFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.web.filter.CharacterEncodingFilter; @Configuration @EnableConfigurationProperties(HttpEncodingProperties.class) // 开启属性注入 @ConditionalOnWebApplication @ConditionalOnClass(CharacterEncodingFilter.class) // 当CharacterEncodingFilter在类路劲的条件下 @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)// 当设置spring.http.encoding=enabled的状况下,若是没有设置默认是true,即符合条件 public class HttpEncodingAutoConfiguration { private final HttpEncodingProperties properties; public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) { this.properties = properties; } @Bean// 使用java方式配置CharacterEncodingFilter的Bean @ConditionalOnMissingBean(CharacterEncodingFilter.class)// 当容器中没有这个Bean public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE)); return filter; } @Bean public LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() { return new LocaleCharsetMappingsCustomizer(this.properties); } private static class LocaleCharsetMappingsCustomizer implements EmbeddedServletContainerCustomizer, Ordered { private final HttpEncodingProperties properties; LocaleCharsetMappingsCustomizer(HttpEncodingProperties properties) { this.properties = properties; } @Override public void customize(ConfigurableEmbeddedServletContainer container) { if (this.properties.getMapping() != null) { container.setLocaleCharsetMappings(this.properties.getMapping()); } } @Override public int getOrder() { return 0; } } }