SpringBootçè¿è¡åçå°±æ¯åºäºSpringBootçèªå¨é ç½®æ¥å®ç°ãæä»¬è¦æ³çç»ç使ç¨SpringBootè¿ä¸æ¡æ¶ææ¯ï¼å°±å¿ é¡»å¯¹å ¶æ·±å ¥å¦ä¹ ã
ä¸ï¼
éæ©SpringBootçä¾èµçæ¬ï¼
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/>
</parent>
é¦å ï¼æä»¬å æ¥çä¸ä¸ï¼å½æä»¬å¯å¨ä¸ä¸ªSpringBooté¡¹ç®æ¶ï¼SpringBoot为æä»¬èªå¨å¯å¨äºåªäºèªå¨é 置类ã
æä½(以ä¸ä¸ç§æ¹å¼ä»»éå ¶ä¸)ï¼
(1)å¨application.propertiesä¸è®¾ç½®å±æ§ï¼
debug=true
ï¼2ï¼éè¿cmdå½ä»¤çªå£è¿è¡xxx.jaræä»¶
java -jar xxx.jar --debug
ï¼3ï¼å¨Idea ä¸è®¾ç½®è¿è¡æ¶åæ°

ç»æï¼
--------------------
--------------------
äºï¼
æ¥ä¸æ¥ï¼æä»¬éè¦å¦ä¹ ä¸ä¸ªæ³¨è§£@SpringBootApplicationï¼è¿ä¸ªæ³¨è§£æ¯ä¸ä¸ªç»å注解ï¼ä»çæ ¸å¿åè½æ¯ç±@EnableAutoConfiguration注解æä¾ã
好çï¼ç¶åæä»¬æ¥çä¸ä¸@EnableAutoConfiguration çæºç ï¼
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
å å¼ä»¬ï¼å¿«çï¼ï¼ï¼è¿å ¶ä¸æä¸ä¸ª@Importæ³¨è§£ï¼æ³¨æå°äºåï¼ï¼ï¼å®çä½ç¨å¯æ¯éå¸¸å ³é®çï¼
å®çä½ç¨å°±æ¯å°AutoConfigurationImportSelectorç±»å¯¼å ¥è³Spring IOC容å¨ãäºæ¯æä»¬å°±è¿å»ççï¼è¿ä¸ªç±»ä¸æä¸ä¸ªselectImportsæ¹æ³ãå ·ä½æºç å¦ä¸ï¼
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.filter(configurations, autoConfigurationMetadata);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return StringUtils.toStringArray(configurations);
}
}
å¨è¿ä¸ªæ¹æ³ä¸ï¼è°ç¨äºAutoConfigurationMetadataLoaderç±»çä¸ä¸ªéææ¹æ³loadMetadata(ClassLoader classLoader)ã
public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
return loadMetadata(classLoader, "META-INF/spring-autoconfigure-metadata.properties");
}
è¿ä¸ªæ¹æ³ç¨æ¥æ«æå ·æ"META-INF/spring-autoconfigure-metadata.properties"æä»¶çjarå ï¼èæä»¬çspring-boot-autoconfigure-2.0.1RELEASE.jaréå°±æspring.factoriesæä»¶,ç¶åæä»¬å°å ¶æå¼ï¼æ¥çä¸ä¸æ¤æä»¶å ·ä½æåªäºèªå¨é ç½®ãå¦å¾æç¤ºï¼
ç¶åæéæ©ä¸ä¸ªæä»¬è¾ä¸ºçæçHttpEncodingAutoConfigurationç±»
@Configuration //è¡¨ç¤ºè¿æ¯ä¸ä¸ªé
置类,以åç¼åçé
ç½®æä»¶ä¸æ ·,ä¹å¯ä»¥ç»å®¹å¨ä¸æ·»å ç»ä»¶
@EnableConfigurationProperties({HttpEncodingProperties.class}) //å¯å¨æå®ç±»çConfigurationPropertiesåè½;å°é
ç½®æä»¶ä¸å¯¹åºçå¼åHttpEncodingPropertiesç»å®èµ·æ¥;å¹¶æHttpEncodingPropertieså å
¥å°ioc容å¨ä¸
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class}) //夿å½åé¡¹ç®ææ²¡æè¿ä¸ªç±»CharacterEncodingFilter ; SpringMVCä¸è¿è¡ä¹±ç è§£å³çè¿æ»¤å¨;
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)//夿é
ç½®æä»¶ä¸æ¯å¦åå¨æä¸ªé
ç½®spring.http.encoding.enabled ;妿ä¸åå¨ï¼å¤æä¹æ¯æç«ç//å³ä½¿æä»¬é
ç½®æä»¶ä¸ä¸é
ç½®pring.http.encoding.enabled=true ,乿¯é»è®¤çæç;
public class HttpEncodingAutoConfiguration {
private final HttpEncodingProperties properties;
//åªæä¸ä¸ªæåæé å¨çæ
åµä¸,åæ°çå¼å°±ä¼ä»å®¹å¨ä¸æ¿
public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
this.properties = properties;
}
@Bean //ç»å®¹å¨ä¸æ·»å ä¸ä¸ªç»ä»¶,è¿ä¸ªç»ä»¶çæäºå¼éè¦ä»propertiesä¸è·å
@ConditionalOnMissingBean //夿容卿²¡æè¿ä¸ªç»ä»¶?
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpEncodingProperties.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpEncodingProperties.Type.RESPONSE));
return filter;
}
@Bean
public HttpEncodingAutoConfiguration.LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
return new HttpEncodingAutoConfiguration.LocaleCharsetMappingsCustomizer(this.properties);
}
private static class LocaleCharsetMappingsCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {
private final HttpEncodingProperties properties;
LocaleCharsetMappingsCustomizer(HttpEncodingProperties properties) {
this.properties = properties;
}
public void customize(ConfigurableServletWebServerFactory factory) {
if (this.properties.getMapping() != null) {
factory.setLocaleCharsetMappings(this.properties.getMapping());
}
}
public int getOrder() {
return 0;
}
}
}
以䏿ºç å°±æ¯æ ¹æ®å½åä¸åçæ¡ä»¶å¤æ,å³å®è¿ä¸ªé 置类æ¯å¦çæ?ä¸ä½è¿ä¸ªé ç½®ç±»çæ ;è¿ä¸ªé 置类就ä¼ç»å®¹å¨ä¸æ·»å åç§ç»ä»¶;è¿äºç»ä»¶ç屿§æ¯ä»å¯¹åºçpropertiesç±»ä¸è·åç,è¿äºç±»éé¢çæ¯ä¸ä¸ªå±æ§åæ¯åé ç½®æä»¶ç»å®ç;
Â
ææå¨é ç½®æä»¶ä¸è½é ç½®ç屿§é½æ¯å¨XxxxPropertiesç±»ä¸å°è£ è ;é ç½®æä»¶è½é ç½®ä»ä¹å°±å¯ä»¥åç §æä¸ªå
è½å¯¹åºçè¿ä¸ªå±æ§ç±»ï¼æ¯å¦ï¼
@ConfigurationProperties(
prefix = "spring.http.encoding"
) //ä»é
ç½®æä»¶ä¸è·åæå®å¼åbeanç屿§è¿è¡ç»å®
public class HttpEncodingProperties {
public static final Charset DEFAULT_CHARSET;
private Charset charset;
private Boolean force;
private Boolean forceRequest;
private Boolean forceResponse;
private Map<Locale, Charset> mapping;
public HttpEncodingProperties() {
this.charset = DEFAULT_CHARSET;
}
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;
}
public boolean shouldForce(HttpEncodingProperties.Type type) {
Boolean force = type == HttpEncodingProperties.Type.REQUEST ? this.forceRequest : this.forceResponse;
if (force == null) {
force = this.force;
}
if (force == null) {
force = type == HttpEncodingProperties.Type.REQUEST;
}
return force;
}
static {
DEFAULT_CHARSET = StandardCharsets.UTF_8;
}
public static enum Type {
REQUEST,
RESPONSE;
private Type() {
}
}
}
æ»ç»ï¼
1) SpringBootå¯å¨ä¼å 载大éçèªå¨é 置类
2) æä»¬çæä»¬éè¦çåè½ææ²¡æSpringBooté»è®¤å好çèªå¨é 置类;
3) æä»¬åæ¥çè¿ä¸ªèªå¨é 置类ä¸å°åºé ç½®äºåªäºç»ä»¶; (åªè¦æä»¬è¦ç¨çç»ä»¶æ,æä»¬å°±ä¸éè¦åæ¥é ç½®äº)
4) ç»å®¹å¨ä¸èªå¨é 置类添å ç»ä»¶çæ¶å,ä¼ä»propertiesç±»ä¸è·åæäºå±æ§ãæä»¬å°±å¯ä»¥å¨é ç½®æä»¶ä¸æå®è¿äºå±æ§çå¼;
5) xxxxAutoConfigurartion :èªå¨é 置类;ç»å®¹å¨ä¸æ·»å ç»ä»¶
  xxxxProperties:å°è£ é ç½®æä»¶ä¸ç¸å ³å±æ§;