{"id":344432,"date":"2023-01-25T03:00:41","date_gmt":"2023-01-25T03:00:41","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=344432"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=344432","title":{"rendered":"<span>Spring Cloud Config \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0443\u043c\u0435\u043b\u0438 \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0442.\u0435. \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0443\u0436\u0435 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u042f \u043f\u0440\u043e\u0432\u0435\u0434\u0443 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u0437\u043e\u0440 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0448\u0435\u043b \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u0438 \u0442\u043e, \u043d\u0430 \u0447\u0435\u043c \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f. <\/p>\n<p>\u041d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f spring boot 2.6.4 \u0438 kotlin 1.5.31. \u0422\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f spring cloud config server, \u0433\u0434\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 backend \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f Git + Vault.<\/p>\n<h2>Spring Cloud Config Server  <\/h2>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043b\u0435\u0433\u0447\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 backend Spring Cloud Config Server \u0444\u0430\u0439\u043b\u043e\u0432\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443:<\/p>\n<pre><code class=\"yaml\">#docker-compose.yml version: '2' services:  config-server-env:    container_name: config-server-env    image: hyness\/spring-cloud-config-server:2.2    ports:      - \"8888:8888\"    environment:      SPRING_PROFILES_ACTIVE: native    volumes:      - .\/config:\/config<\/code><\/pre>\n<p>\u041f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f refresh_app \u0441 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u043c dev \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e .\/config:  <\/p>\n<pre><code class=\"yaml\">#config\/refresh_app-dev.yml refresh:   property1: 1<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0434\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043a\u0430\u043a\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043e\u0442\u0434\u0430\u0435\u0442 Spring Cloud Config Server \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 refresh_app:  <\/p>\n<pre><code class=\"bash\"> >curl http:\/\/localhost:8888\/refresh_app\/dev {\"name\":\"refresh_app\",\"profiles\":[\"dev\"],\"label\":null,\"version\":null,\"state\":null,\"propertySources\":[{\"name\":\"file:config\/refresh_app-dev.yml\",\"source\":{\"refresh.property1\":1}}]}<\/code><\/pre>\n<h2>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f Spring Cloud Config Client (\u0441\u0435\u0440\u0432\u0438\u0441\u0430 refresh_app)  <\/h2>\n<pre><code class=\"java\">\/\/build.gradle .............. implementation \"org.springframework.boot:spring-boot-starter\" implementation \"org.springframework.cloud:spring-cloud-starter-config\" implementation \"org.springframework.boot:spring-boot-starter-actuator\" implementation \"org.springframework.boot:spring-boot-starter-web\" ..............<\/code><\/pre>\n<pre><code class=\"javascript\">#application.properties spring.config.import=optional:configserver:http:\/\/localhost:8888 spring.application.name=refresh_app server.port=8080 management.endpoints.web.exposure.include=*<\/code><\/pre>\n<h2>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c<\/h2>\n<p>\u0414\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 refresh_app \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 Spring Cloud Config Server \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0444\u0430\u0439\u043b config\/refresh_app-dev.yml. \u0427\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0442\u0434\u0430\u0435\u0442 \u0443\u0436\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043d\u043e\u0432\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 GET <a href=\"http:\/\/localhost:8888\/refresh_app\/dev\" rel=\"noopener noreferrer nofollow\">\/refresh_app\/dev<\/a> \u043a spring cloud config server.  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f actuator endpoints \u0441\u0435\u0440\u0432\u0438\u0441\u0430 refresh_app:   <\/p>\n<ul>\n<li>\n<p>POST \/actuator\/refresh  <\/p>\n<p>\u0412\u044b\u0437\u043e\u0432 \u0434\u0430\u043d\u043d\u043e\u0433\u043e endpoint \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0443 Spring Cloud Server. \u0421\u0432\u0435\u0440\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a properties, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c, \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 Environment \u0441\u0435\u0440\u0432\u0438\u0441\u0430. Response body \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 Set \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0445 properties. \u0422\u0430\u043a\u0436\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0435 EnvironmentChangeEvent, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0442\u043e\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 Set \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439, \u043d\u0430 \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f.   <\/p>\n<\/li>\n<li>\n<p>GET \/actuator\/env  <\/p>\n<p>Response body \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 Environment \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0434\u0442\u044f\u043d\u0443\u043b\u0430\u0441\u044c.   <\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c actuator endpoints \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e:  <\/p>\n<ul>\n<li>\n<p>\u0432 <em>build.gradle<\/em> \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 spring-boot-starter-actuator \u0438 spring-boot-starter-web<\/p>\n<\/li>\n<li>\n<p>\u0432<em> application.properties<\/em> \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c &#171;<em>management.endpoints.web.exposure.include=*<\/em>&#187;  <\/p>\n<\/li>\n<\/ul>\n<h2>\u041a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e  <\/h2>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440: \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f refresh.property1. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0442\u0430\u043a\u0443\u044e \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0442\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438.<\/p>\n<p>1) Environment<\/p>\n<pre><code class=\"kotlin\">@RestController class Rest1(val applicationContext: ApplicationContext) {    @GetMapping(\"\/test1\")    fun test(): ResponseEntity&lt;String> =      ResponseEntity.ok(applicationContext.environment[\"refresh.property1\"]) }<\/code><\/pre>\n<p> 2) @ConfigurationProperties  <\/p>\n<pre><code class=\"kotlin\">@ConfigurationProperties(\"refresh\") class TestProperties {    lateinit var property1: String } @RestController class Rest2(val testBean: TestProperties ) {    @GetMapping(\"\/test2\")    fun test(): ResponseEntity&lt;String> = ResponseEntity.ok(testBean.property1) }<\/code><\/pre>\n<p>\u0425\u043e\u0447\u0443 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b kotlin \u0438 spring. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u043e \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 runtime:  <\/p>\n<pre><code class=\"kotlin\">@ConstructorBinding  @ConfigurationProperties(\"refresh\")  data class TestBean(val property1: String)  @ConstructorBinding  @ConfigurationProperties(\"refresh\")  data class TestBean(var property1: String)<\/code><\/pre>\n<p>3) @RefreshScope + @Value <\/p>\n<pre><code class=\"kotlin\">@RefreshScope @RestController class Rest3(@Value(\"\\${refresh.property1}\") val property1: String) {    @GetMapping(\"\/test3\")    fun test(): ResponseEntity&lt;String> = ResponseEntity.ok(property1) }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0442\u0440\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 refresh.property1 \u043f\u043e\u0441\u043b\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e Spring Cloud Config Server \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 POST \/actuator\/refresh.  <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044e \u0431\u0438\u043d\u043e\u0432, \u043d\u043e \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434.  <\/p>\n<h2>\u0420\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0431\u0438\u043d\u043e\u0432 <\/h2>\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044e \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u041d\u043e \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 properties \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.   <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0441\u0442\u044c \u0431\u0438\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0435\u0440\u0442\u043a\u043e\u0439 \u043d\u0430\u0434 \u0441\u043a\u0430\u0436\u0435\u043c KafkaConsumer. \u0412 @PostConstruct \u043c\u0435\u0442\u043e\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a Consumer, \u0432 @PreDestroy \u043c\u0435\u0442\u043e\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0438 \u0434\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Consumer. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u0438\u043d \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 Environment \u0438 ,\u0435\u0441\u043b\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043d\u0438\u043c properties \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c, \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f. \u0427\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 &#8212; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u044b\u0437\u043e\u0432 @Predestroy \u043c\u0435\u0442\u043e\u0434\u0430 \u0438 \u0432\u044b\u0437\u043e\u0432 @PostConstruct \u043c\u0435\u0442\u043e\u0434\u0430 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0443\u0436\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438.  <\/p>\n<p>\u041a\u0430\u043a \u0431\u044b\u043b\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0440\u0430\u043d\u0435\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a \u0441\u0435\u0440\u0432\u0438\u0441\u0443 POST \/actuator\/refresh \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f EnvironmentChangeEvent \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0438\u0437\u043c\u0435\u043d\u0438\u0432\u0448\u0438\u0445\u0441\u044f properties, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443.  <\/p>\n<p>\u0422.\u0435. \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 Bean Post Processor \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0435\u0441\u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 properties \u0431\u044b\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u044b. \u042f \u0432\u0432\u0435\u043b \u043d\u043e\u0432\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 @Refreshable \u0438 @Refresh:  <\/p>\n<pre><code class=\"kotlin\">@Target(ElementType.METHOD, ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) annotation class Refreshable(val property: String)  @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) annotation class Refresh<\/code><\/pre>\n<p>@Refreshable \u0437\u0430\u0434\u0430\u0435\u0442 property \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u0431\u0438\u043d \u0438 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435. @Refresh &#8212; \u0434\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d, \u0435\u0441\u043b\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0431\u0438\u043d\u043e\u043c property \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u044b.     <\/p>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043e\u0434\u043d\u043e\u0439 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 @Refreshable \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u043d \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u043f\u0440\u0438\u043d\u0433\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043d\u043e \u043f\u0440\u0438\u0448\u043b\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 \u043b\u0443\u0447\u0448\u0435 \u0434\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e @Refresh.  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Bean Post Processor:  <\/p>\n<pre><code class=\"kotlin\">class RefreshBeanPostProcessor(private val applicationContext: GenericApplicationContext) : BeanPostProcessor {     private val refreshPropertyTasks = mutableListOf&lt;RefreshPropertyTask>()     override fun postProcessBeforeInitialization(bean: Any, beanName: String): Any {        (getRefreshablePropertyByBean(bean) ?: getRefreshablePropertyByBeanDefinition(beanName))            ?.let { property ->                bean.javaClass.methods                    .firstOrNull { it.getAnnotation(Refresh::class.java) != null }                    ?.let { method ->                       refreshPropertyTasks.add(RefreshPropertyTask(property)                                                { method.invoke(bean) }) }            }        return bean    }     @PostConstruct    fun init() {        applicationContext.addApplicationListener { event ->            if (event is EnvironmentChangeEvent) {                onApplicationEvent(event)            }        }    }     private fun onApplicationEvent(event: EnvironmentChangeEvent) {        refreshPropertyTasks            .filter { task -> event.keys.firstOrNull { key -> key.startsWith(task.property) } != null }            .forEach { task ->                try {                    log.info(\"Update task ${task.property}\")                    task.action()                } catch (ex: Exception) {                    log.error(\"Error for task ${task.property}\", ex)                }            }    }     private data class RefreshPropertyTask(val property: String, val action: () -> Unit)     private fun getRefreshablePropertyByBean(bean: Any): String? =        bean.javaClass.getAnnotation(Refreshable::class.java)?.property     private fun getRefreshablePropertyByBeanDefinition(beanName: String): String? =        applicationContext.beanFactory            .let { kotlin.runCatching { it.getBeanDefinition(beanName) }.getOrNull() }            ?.source            ?.takeIf { it is AnnotatedTypeMetadata }            ?.let { it as AnnotatedTypeMetadata }            ?.getAnnotationAttributes(Refreshable::class.java.name)            ?.let { it[Refreshable::property.name] as String? } } <\/code><\/pre>\n<p>\u0412\u0430\u0436\u043d\u043e \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c @DependsOn(&#171;configurationPropertiesRebinder&#187;). configurationPropertiesRebinder &#8212; \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 @ConfigurationProperties \u043a\u043b\u0430\u0441\u0441\u044b. \u041e\u043d \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 ApplicationListener&lt;EnvironmentChangeEvent> \u043a\u0430\u043a \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 Bean Post Processor, \u0438, \u0435\u0441\u043b\u0438 \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 ApplicationListener \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u0442\u043e\u044f\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0448\u0435\u0433\u043e, \u0442\u043e \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043b\u0430\u0441\u0441\u044b @ConfigurationProperties \u0431\u0443\u0434\u0443\u0442 \u0435\u0449\u0435 \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u0438 \u043d\u0430\u0448\u0430 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u0441 \u043d\u0435\u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 @ConfigurationProperties.  <\/p>\n<pre><code class=\"kotlin\">@DependsOn(\"configurationPropertiesRebinder\") @Bean fun refreshBeanPostProcessor(ctx: GenericApplicationContext) =    RefreshBeanPostProcessor(ctx)<\/code><\/pre>\n<p>\u042d\u0442\u043e \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u043c, \u0447\u0442\u043e ApplicationListener \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 Bean Post Processor \u0431\u0443\u0434\u0435\u0442 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u043f\u043e\u0441\u043b\u0435 configurationPropertiesRebinder \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435.  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:  <\/p>\n<pre><code class=\"kotlin\">@ConfigurationProperties(\"refresh\") class TestProperties{    lateinit var property1: String    lateinit var property2: String }  @Refreshable(\"refresh\") @Service class Bean1(testProperties: TestProperties){       @PostConstruct fun init(){}    @PreDestroy fun destroy(){}       @Refresh    fun refresh(){        init()        destroy()    } }  class Bean2(testProperties: TestProperties){     @PostConstruct fun init(){}    @PreDestroy fun destroy(){}     @Refresh    fun refresh(){        init()        destroy()    } }  @Configuration class TestConfiguration{     @Refreshable(\"refresh\")    @Bean    fun bean2(testProperties: TestProperties) = Bean2(testProperties) }<\/code><\/pre>\n<h2>\u0410\u0432\u0442\u043e\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 Environment \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/h2>\n<p>Spring Cloud Config Server \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u0445 \u0438 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c POST \/actuator\/refresh.   <\/p>\n<p>\u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u0441\u0442\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Spring Cloud Bus. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u043d\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u0438 Spring Cloud Config Server \u0447\u0435\u0440\u0435\u0437 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u0414\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b Kafka, RabbitMQ \u0438 \u0434\u0440. \u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u043c GET \/monitor Spring Cloud Config Server \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u043c\u0435\u043d \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u0447\u0435\u0440\u0435\u0437 topic Kafka. \u0415\u0441\u043b\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 backend \u0434\u043b\u044f Spring Cloud Config Server \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 webhook, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432 GET \/monitor \u0447\u0435\u0440\u0435\u0437 webhook. \u042f \u043f\u043e\u043a\u0430 \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0442.\u043a. \u043f\u043e\u043a\u0430 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u043a\u0430\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.  <\/p>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0440\u0435\u0448\u0438\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a, \u0447\u0442\u043e \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0432\u0441\u0435\u0433\u043e \u0432\u0441\u0435\u0445 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 \u0432\u0441\u0435\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e \u043e\u043a\u043e\u043b\u043e 100.  <\/p>\n<p>\u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 Environment:  <\/p>\n<pre><code class=\"kotlin\">class RefreshEventPublisherScheduler(    private val refreshSchedulerProperties: RefreshSchedulerProperties,    private val applicationEventPublisher: ApplicationEventPublisher ) {     companion object : Log()     private val executor: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()     @PostConstruct    fun init() {        schedule()    }     private fun schedule() {        executor.schedule(            {                if (refreshSchedulerProperties.enabled) {                    publishRefreshEvent()                }                schedule()            },            refreshSchedulerProperties.interval.toMillis(),            TimeUnit.MILLISECONDS        )    }     private fun publishRefreshEvent() {        applicationEventPublisher.publishEvent(            RefreshEvent(                this,                \"Refresh event\",                \"Refresh scope\"            )        )    } }<\/code><\/pre>\n<p>\u0422.\u0435. \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 publishRefreshEvent(), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u044b\u0437\u043e\u0432\u0443 POST \/actuator\/refresh.   <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 Bean Post Processor \u0438 RefreshEventPublisherScheduler \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0440\u0442\u0435\u0440 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0438\u043d\u043e\u0432.  <\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/712628\/\"> https:\/\/habr.com\/ru\/post\/712628\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0443\u043c\u0435\u043b\u0438 \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0442.\u0435. \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0443\u0436\u0435 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u042f \u043f\u0440\u043e\u0432\u0435\u0434\u0443 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u0437\u043e\u0440 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0448\u0435\u043b \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u0438 \u0442\u043e, \u043d\u0430 \u0447\u0435\u043c \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f. <\/p>\n<p>\u041d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f spring boot 2.6.4 \u0438 kotlin 1.5.31. \u0422\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f spring cloud config server, \u0433\u0434\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 backend \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f Git + Vault.<\/p>\n<h2>Spring Cloud Config Server  <\/h2>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043b\u0435\u0433\u0447\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 backend Spring Cloud Config Server \u0444\u0430\u0439\u043b\u043e\u0432\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443:<\/p>\n<pre><code class=\"yaml\">#docker-compose.yml version: '2' services:  config-server-env:    container_name: config-server-env    image: hyness\/spring-cloud-config-server:2.2    ports:      - \"8888:8888\"    environment:      SPRING_PROFILES_ACTIVE: native    volumes:      - .\/config:\/config<\/code><\/pre>\n<p>\u041f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f refresh_app \u0441 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u043c dev \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e .\/config:  <\/p>\n<pre><code class=\"yaml\">#config\/refresh_app-dev.yml refresh:   property1: 1<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0434\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043a\u0430\u043a\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043e\u0442\u0434\u0430\u0435\u0442 Spring Cloud Config Server \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 refresh_app:  <\/p>\n<pre><code class=\"bash\"> >curl http:\/\/localhost:8888\/refresh_app\/dev {\"name\":\"refresh_app\",\"profiles\":[\"dev\"],\"label\":null,\"version\":null,\"state\":null,\"propertySources\":[{\"name\":\"file:config\/refresh_app-dev.yml\",\"source\":{\"refresh.property1\":1}}]}<\/code><\/pre>\n<h2>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f Spring Cloud Config Client (\u0441\u0435\u0440\u0432\u0438\u0441\u0430 refresh_app)  <\/h2>\n<pre><code class=\"java\">\/\/build.gradle .............. implementation \"org.springframework.boot:spring-boot-starter\" implementation \"org.springframework.cloud:spring-cloud-starter-config\" implementation \"org.springframework.boot:spring-boot-starter-actuator\" implementation \"org.springframework.boot:spring-boot-starter-web\" ..............<\/code><\/pre>\n<pre><code class=\"javascript\">#application.properties spring.config.import=optional:configserver:http:\/\/localhost:8888 spring.application.name=refresh_app server.port=8080 management.endpoints.web.exposure.include=*<\/code><\/pre>\n<h2>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c<\/h2>\n<p>\u0414\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 refresh_app \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 Spring Cloud Config Server \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0444\u0430\u0439\u043b config\/refresh_app-dev.yml. \u0427\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0442\u0434\u0430\u0435\u0442 \u0443\u0436\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043d\u043e\u0432\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 GET <a href=\"http:\/\/localhost:8888\/refresh_app\/dev\" rel=\"noopener noreferrer nofollow\">\/refresh_app\/dev<\/a> \u043a spring cloud config server.  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f actuator endpoints \u0441\u0435\u0440\u0432\u0438\u0441\u0430 refresh_app:   <\/p>\n<ul>\n<li>\n<p>POST \/actuator\/refresh  <\/p>\n<p>\u0412\u044b\u0437\u043e\u0432 \u0434\u0430\u043d\u043d\u043e\u0433\u043e endpoint \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0443 Spring Cloud Server. \u0421\u0432\u0435\u0440\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a properties, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c, \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 Environment \u0441\u0435\u0440\u0432\u0438\u0441\u0430. Response body \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 Set \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0445 properties. \u0422\u0430\u043a\u0436\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0435 EnvironmentChangeEvent, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0442\u043e\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 Set \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439, \u043d\u0430 \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f.   <\/p>\n<\/li>\n<li>\n<p>GET \/actuator\/env  <\/p>\n<p>Response body \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 Environment \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0434\u0442\u044f\u043d\u0443\u043b\u0430\u0441\u044c.   <\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c actuator endpoints \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e:  <\/p>\n<ul>\n<li>\n<p>\u0432 <em>build.gradle<\/em> \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 spring-boot-starter-actuator \u0438 spring-boot-starter-web<\/p>\n<\/li>\n<li>\n<p>\u0432<em> application.properties<\/em> \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c &#171;<em>management.endpoints.web.exposure.include=*<\/em>&#187;  <\/p>\n<\/li>\n<\/ul>\n<h2>\u041a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e  <\/h2>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440: \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f refresh.property1. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0442\u0430\u043a\u0443\u044e \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0442\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438.<\/p>\n<p>1) Environment<\/p>\n<pre><code class=\"kotlin\">@RestController class Rest1(val applicationContext: ApplicationContext) {    @GetMapping(\"\/test1\")    fun test(): ResponseEntity&lt;String> =      ResponseEntity.ok(applicationContext.environment[\"refresh.property1\"]) }<\/code><\/pre>\n<p> 2) @ConfigurationProperties  <\/p>\n<pre><code class=\"kotlin\">@ConfigurationProperties(\"refresh\") class TestProperties {    lateinit var property1: String } @RestController class Rest2(val testBean: TestProperties ) {    @GetMapping(\"\/test2\")    fun test(): ResponseEntity&lt;String> = ResponseEntity.ok(testBean.property1) }<\/code><\/pre>\n<p>\u0425\u043e\u0447\u0443 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b kotlin \u0438 spring. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u043e \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 runtime:  <\/p>\n<pre><code class=\"kotlin\">@ConstructorBinding  @ConfigurationProperties(\"refresh\")  data class TestBean(val property1: String)  @ConstructorBinding  @ConfigurationProperties(\"refresh\")  data class TestBean(var property1: String)<\/code><\/pre>\n<p>3) @RefreshScope + @Value <\/p>\n<pre><code class=\"kotlin\">@RefreshScope @RestController class Rest3(@Value(\"\\${refresh.property1}\") val property1: String) {    @GetMapping(\"\/test3\")    fun test(): ResponseEntity&lt;String> = ResponseEntity.ok(property1) }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0442\u0440\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 refresh.property1 \u043f\u043e\u0441\u043b\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e Spring Cloud Config Server \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 POST \/actuator\/refresh.  <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044e \u0431\u0438\u043d\u043e\u0432, \u043d\u043e \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434.  <\/p>\n<h2>\u0420\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0431\u0438\u043d\u043e\u0432 <\/h2>\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044e \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u041d\u043e \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 properties \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.   <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0441\u0442\u044c \u0431\u0438\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0435\u0440\u0442\u043a\u043e\u0439 \u043d\u0430\u0434 \u0441\u043a\u0430\u0436\u0435\u043c KafkaConsumer. \u0412 @PostConstruct \u043c\u0435\u0442\u043e\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a Consumer, \u0432 @PreDestroy \u043c\u0435\u0442\u043e\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0438 \u0434\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Consumer. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u0438\u043d \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 Environment \u0438 ,\u0435\u0441\u043b\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043d\u0438\u043c properties \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c, \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f. \u0427\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 &#8212; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u044b\u0437\u043e\u0432 @Predestroy \u043c\u0435\u0442\u043e\u0434\u0430 \u0438 \u0432\u044b\u0437\u043e\u0432 @PostConstruct \u043c\u0435\u0442\u043e\u0434\u0430 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0443\u0436\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438.  <\/p>\n<p>\u041a\u0430\u043a \u0431\u044b\u043b\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0440\u0430\u043d\u0435\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a \u0441\u0435\u0440\u0432\u0438\u0441\u0443 POST \/actuator\/refresh \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f EnvironmentChangeEvent \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0438\u0437\u043c\u0435\u043d\u0438\u0432\u0448\u0438\u0445\u0441\u044f properties, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443.  <\/p>\n<p>\u0422.\u0435. \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 Bean Post Processor \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0435\u0441\u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 properties \u0431\u044b\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u044b. \u042f \u0432\u0432\u0435\u043b \u043d\u043e\u0432\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 @Refreshable \u0438 @Refresh:  <\/p>\n<pre><code class=\"kotlin\">@Target(ElementType.METHOD, ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) annotation class Refreshable(val property: String)  @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) annotation class Refresh<\/code><\/pre>\n<p>@Refreshable \u0437\u0430\u0434\u0430\u0435\u0442 property \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u0431\u0438\u043d \u0438 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435. @Refresh &#8212; \u0434\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d, \u0435\u0441\u043b\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0431\u0438\u043d\u043e\u043c property \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u044b.     <\/p>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043e\u0434\u043d\u043e\u0439 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 @Refreshable \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u043d \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u043f\u0440\u0438\u043d\u0433\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043d\u043e \u043f\u0440\u0438\u0448\u043b\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 \u043b\u0443\u0447\u0448\u0435 \u0434\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e @Refresh.  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Bean Post Processor:  <\/p>\n<pre><code class=\"kotlin\">class RefreshBeanPostProcessor(private val applicationContext: GenericApplicationContext) : BeanPostProcessor {     private val refreshPropertyTasks = mutableListOf&lt;RefreshPropertyTask>()     override fun postProcessBeforeInitialization(bean: Any, beanName: String): Any {        (getRefreshablePropertyByBean(bean) ?: getRefreshablePropertyByBeanDefinition(beanName))            ?.let { property ->                bean.javaClass.methods                    .firstOrNull { it.getAnnotation(Refresh::class.java) != null }                    ?.let { method ->                       refreshPropertyTasks.add(RefreshPropertyTask(property)                                                { method.invoke(bean) }) }            }        return bean    }     @PostConstruct    fun init() {        applicationContext.addApplicationListener { event ->            if (event is EnvironmentChangeEvent) {                onApplicationEvent(event)            }        }    }     private fun onApplicationEvent(event: EnvironmentChangeEvent) {        refreshPropertyTasks            .filter { task -> event.keys.firstOrNull { key -> key.startsWith(task.property) } != null }            .forEach { task ->                try {                    log.info(\"Update task ${task.property}\")                    task.action()                } catch (ex: Exception) {                    log.error(\"Error for task ${task.property}\", ex)                }            }    }     private data class RefreshPropertyTask(val property: String, val action: () -> Unit)     private fun getRefreshablePropertyByBean(bean: Any): String? =        bean.javaClass.getAnnotation(Refreshable::class.java)?.property     private fun getRefreshablePropertyByBeanDefinition(beanName: String): String? =        applicationContext.beanFactory            .let { kotlin.runCatching { it.getBeanDefinition(beanName) }.getOrNull() }            ?.source            ?.takeIf { it is AnnotatedTypeMetadata }            ?.let { it as AnnotatedTypeMetadata }            ?.getAnnotationAttributes(Refreshable::class.java.name)            ?.let { it[Refreshable::property.name] as String? } } <\/code><\/pre>\n<p>\u0412\u0430\u0436\u043d\u043e \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c @DependsOn(&#171;configurationPropertiesRebinder&#187;). configurationPropertiesRebinder &#8212; \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 @ConfigurationProperties \u043a\u043b\u0430\u0441\u0441\u044b. \u041e\u043d \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 ApplicationListener&lt;EnvironmentChangeEvent> \u043a\u0430\u043a \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 Bean Post Processor, \u0438, \u0435\u0441\u043b\u0438 \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 ApplicationListener \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u0442\u043e\u044f\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0448\u0435\u0433\u043e, \u0442\u043e \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043b\u0430\u0441\u0441\u044b @ConfigurationProperties \u0431\u0443\u0434\u0443\u0442 \u0435\u0449\u0435 \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u0438 \u043d\u0430\u0448\u0430 \u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u0441 \u043d\u0435\u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 @ConfigurationProperties.  <\/p>\n<pre><code class=\"kotlin\">@DependsOn(\"configurationPropertiesRebinder\") @Bean fun refreshBeanPostProcessor(ctx: GenericApplicationContext) =    RefreshBeanPostProcessor(ctx)<\/code><\/pre>\n<p>\u042d\u0442\u043e \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u043c, <\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-344432","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/344432","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=344432"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/344432\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=344432"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=344432"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=344432"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}