在瞭解了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; } } }