【SprinBoot】E n a b l e ConfigurationProperties注釈の原理と使用(バージョン2.0.6)

6607 ワード

1 E n a b l e C o n f i gurationPropertiesプロパティ構成開始フローチャート


SpringBootの注記では、@ConfigurationProperties注釈付きBeanの有効なサポートについて説明しています.この注釈は,@ConfigurationProperties注釈を持つクラスをSpringコンテナのBeanに注入する便利な方法を提供することができる. 
コア:
A:C o n f i g u r ationPropertiesBeanRegistrar@E n a b l e C o n f i g u r ationPropertiesのvalue配列Typeを容器に注入する
B:C o n f i g u r a t i o n P r e t i e sBindingPostProcessorは、@C o n f i g u r a t i o n P r e ties注記のBeanに対して属性値の設定を行います

2詳細な分析プロセス:


2.1 boot注記自動構成開始プロファイルベース、およびSpringBootが提供する自動構成によるオブジェクトの初期化アプリケーション.(プロファイル:アプリケーション.properties)Spring Bootは起動時に依存するStarterパッケージからresources/META-INF/springを探します.factoriesファイルは、ファイルに設定されているJarパッケージに基づいて、プロジェクトに依存するJarパッケージをスキャンします.spring.factories構成AutoConfigureクラスをロードし、@Conditional注記の条件に従って、自動構成を行い、BeanをSpring Contextに注入します.Spring Bootは起動時に、Spring Boot Starterの構成情報を約束通りに読み取り、構成情報に基づいてリソースを初期化し、Springコンテナに注入します.このようにSpring Bootの起動が完了すると、すべてのリソースが用意され、使用中に対応するBeanリソースを直接注入すればよい.
2.2一言まとめ
@SpringBootApplication=[@Configuration@ComponentScan@EnableAutoConfiguration]ここで@EnableAutoConfigurationは自動構成を実現する入口であり、この注釈はまた@Import注釈によってAutoConfiguration ImportSelectorに導入され、このクラスにMETA-INF/springがロードされる.factoriesの構成情報.そしてEnableAutoConfigurationをkeyとするデータを選別し、IOCコンテナにロードして自動配置機能を実現! 
  2.3 spring.factoriesファイル
ローカル倉庫で:.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.0.6.RELEASE/spring-boot-autoconfigure-2.0.6.RELEASE.jar!/META-INF/spring.factories.EnableAutoConfigurationはkeyのリストです.たとえば、プロファイルに次のようなものが含まれています.
 
org.springframework.boot.autoconfigure.EnableAutoConfiguration=[...,org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\,...]
 
彼の役割は、Automatically binds and validates any bean annotated with@ConfigurationPropertiesです.このクラスには何の内容もありませんが、実際にはコンフィギュレーションプロパティの自動構成を識別するための識別クラスにすぎません.重要なのは@コンフィギュレーションと@Enableコンフィギュレーションプロパティです.このクラスがSpringBootで唯一引用された場所はspringです.factoriesで.したがって、C o n f i g u r a t r o p r e t i esAutoConfigurationはIOCコンテナにロードされます.C o n f i g u r a t i o n P r e t i esAutoConfigurationがロードされると、@E n a b l e C o n f i g u r t i o n P r e P r tiesImportSelectorが解析され、このクラスもロードされます(org.springframework.context.annotation.C onfigurationClassParser#processImports)がインスタンス化され、そのselectImportsメソッドが呼び出されます.selectImportsメソッドは、C o n f i g u r a t i o n P r o p e r t i e s B u n d i n g PostProcessorRegistrarとC o n f i g u r t i o n P r e s BeanRegistrarの全クラス限定名を返します. 
P u b l i c c l a s C o n f i g u r a t r o p r t i e s B n d i n g P o s t P o s t P r e s t i n g o n P e n P e n D i n g i o n Registrarインターフェースが実装され、registerBeanDefinitionメソッドが(org.springframework.context.annotation.C o n f i g u r ationClassBeanDefinitionReader#loadBeanDefinitions)で呼び出されます.最終的にC o n f i g u r a t i o n P r e t i e sBindingPostProcessorはコンテナに注入されます.つまり、@C o n f i g u r a t i o n P r e tiesBindingPostProcessorはorg.springframework.beans.factory.config.BeanPostProcessorインタフェースがコンフィギュレーションP o n f i g u r a tionPropertiesBindingPostProcessorに対して単独でbind処理を行うため、属性値の構成を行います.
C o n f i g u r a t i o n P r e t i e s BeanRegistrarは、I m p o r t h i n D e f i n i t i o n Registrar拡張点を実現し、@E n a b l e C o n f i g u r a t i o n P r e sのvalueをコンテナに注入し、throw if type no@ConfigurationP r ties.
その他の構成クラスの例:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=[...,org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\,...] 
では、E m b e d e d e d e d W e b ServerFactoryCustomizerAutoConfigurationがIOCコンテナにロードされます.一方、E m b e d e d e d W e b S e r v e r F o c t oryCustomizerAutoConfigurationクラスには@E n a b l e ConfigurationProperties(ServerProperties.class)注記があります.ServicePropertiesは、オンラインの2つのコアクラスを使用してコンテナに注入されます. 

3 tomcat server.tomcat.background-processor-delay構成例debug

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

	/**
	 * Nested configuration if Tomcat is being used.
	 */
	@Configuration
	@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })
	public static class TomcatWebServerFactoryCustomizerConfiguration {
	    ...
	}


}


//  
org.springframework.beans.factory.support.ConstructorResolver#createArgumentArray


//  :name.string.equalsIgnoreCase("server.tomcat.background-processor-delay")
org.springframework.boot.context.properties.bind.Binder#bindObject   tomcat 


// bind   propertyName.equalsIgnoreCase("background-processor-delay") || propertyName.equalsIgnoreCase("backgroundProcessorDelay")
org.springframework.boot.context.properties.bind.JavaBeanBinder#bind

//  : property.name.equalsIgnoreCase("timeout")  redis 
org.springframework.boot.context.properties.bind.JavaBeanBinder#bind


// convert   23S->Duration
org.springframework.core.convert.support.GenericConversionService#convert(java.lang.Object, org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor)

//     
org.springframework.util.ObjectUtils#nullSafeEquals 

//     source.name.equalsIgnoreCase("systemEnvironment")
// applicationConfig: [classpath:/application-prod.properties]   
org.springframework.boot.context.properties.source.SpringConfigurationPropertySources#adapt

 


4@E n a b l e C o n f i gurationPropertiesを使用したカスタム構成プロパティの実装(標準的なアプローチ)


(実はAppPropertiesに@Componentを付けて1 3の2つのクラスでもOK)
// 1  
@Data
@ConfigurationProperties(prefix = "my.app",ignoreUnknownFields = true)
public class AppProperties {
    private String appName;
    private String appVersion;

    @Override
    public String toString() {
        return "AppProperties{" +
                "appName='" + appName + '\'' +
                ", appVersion='" + appVersion + '\'' +
                '}';
    }
}

// 2  
@Configuration//   @Component
@EnableConfigurationProperties(value ={ AppProperties.class })
public class MyAppStartor {
}

// 3  
@RestController
public class PropertiesConfigurationController {


    @Autowired
    @Lazy
    private AppProperties appProperties;

    @GetMapping("/index")
    public String getProperties(){
        return appProperties.toString();
    }
}

// 4  
my.app.appName=zwwAPP
my.app.appVersion=1.0.0


// 5  
➜  ~ curl -X GET 127.0.0.1:8080/index
AppProperties{appName='zwwAPP', appVersion='1.0.0'}%