{"id":444695,"date":"2025-01-10T21:02:08","date_gmt":"2025-01-10T21:02:08","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=444695"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=444695","title":{"rendered":"<span>Simple Spring (\u043f\u043e\u043b\u043d\u044b\u0439 \u0444\u0430\u0440\u0448)<\/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>\u0414\u043e\u0440\u043e\u0433\u043e\u0439 \u0434\u0440\u0443\u0433, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c \u0447\u0442\u043e \u0442\u044b \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440 (\u0430 \u0442\u0430\u043a\u0436\u0435 \u0431\u044d\u043a \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0444\u0440\u043e\u043d\u0442-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 \u043e\u0434\u043d\u043e\u043c \u043b\u0438\u0446\u0435) \u0438 \u043e\u0442 \u0442\u0435\u0431\u044f \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u044d\u0442\u0438\u043c \u0438 \u0437\u0430\u0439\u043c\u0451\u043c\u0441\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044f \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044f\u043c\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043d\u0430 \u043f\u0440\u043e\u0434-\u0441\u0442\u0435\u043d\u0434\u0435.<\/p>\n<p>\u0422\u043e\u0447\u043d\u0435\u0435, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438 \u0443\u0432\u044f\u0436\u0435\u043c \u0432 \u0435\u0434\u0438\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443<\/p>\n<ul>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 (AuthService) \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 oauth 2.0 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u044b \u043a \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 (SpringCloudConfig) \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0441\u0435\u043c \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438. \u0422\u0430\u043a\u0436\u0435 \u043e\u043d \u0434\u0430\u0441\u0442 \u043d\u0430\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\/\u0438\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0413\u0435\u0439\u0442\u0432\u0435\u0439 (SpringCloudGateway) \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438\u0437 \u0443\u0441\u043b\u043e\u0432\u043d\u043e \u043d\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u0437\u043e\u043d\u044b \u0432 \u0443\u0441\u043b\u043e\u0432\u043d\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u0437\u043e\u043d\u0443 \u0433\u0434\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 (SpringBootAdminServer) \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 1 (WebApplication) \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u043e\u0439 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441 \u0441 \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a \u0411\u0414 \u0438 \u0440\u0443\u0447\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0440\u0432\u0435\u0440-\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 2 (WebSecurityApplication) \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u043e\u0439 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441 \u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b spring security<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 3 (WebGenerateApplication) \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u043e \u0437\u0430\u0442\u043e \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430 &#171;api first&#187; \u0438 \u0430\u0432\u0442\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a68\/c0a\/5bb\/a68c0a5bbfb8d950ab7ddcf5d0d3f5d9.png\" width=\"1246\" height=\"710\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a68\/c0a\/5bb\/a68c0a5bbfb8d950ab7ddcf5d0d3f5d9.png\"\/><\/figure>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431: <a href=\"https:\/\/github.com\/upswet\/SimpleSpringExample\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/upswet\/SimpleSpringExample<\/a><\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0438 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b<\/p>\n<ul>\n<li>\n<p>Spring: spring web, spring data, spring security (\u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e), spring actuator, spring cloud config, spring cloud gateway, spring boot admin<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 oauth 2 (\u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e)<\/p>\n<\/li>\n<li>\n<p>api-first (\u0441 \u0430\u0432\u0442\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u043a\u043e\u0434\u0430 \u0447\u0435\u0440\u0435\u0437 org.openapi.generator)<\/p>\n<\/li>\n<li>\n<p>gradle<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u043a\u0430\u043a \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0438\u043b\u0438 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435.<br \/>\u0417\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u0442\u0430\u043a\u0438\u0435 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0432\u0435\u0449\u0438, \u043a\u0430\u043a<\/p>\n<ul>\n<li>\n<p>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 \u0431\u0440\u043e\u043a\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 Apache Kafka<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u0435\u0441\u0442\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 spring cloud eureka. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u0440\u0438\u0441\u043a\u043d\u0443 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0442\u044c \u0447\u0442\u043e \u043e\u043d \u0432\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0434\u043e\u043a\u043a\u0435\u0440-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0438 \u0445\u043e\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0445\u043e\u0442\u044f \u0431\u044b \u0434\u0430\u0436\u0435 docker compose), \u0430 \u043b\u0443\u0447\u0448\u0435 \u0447\u0442\u043e \u0442\u0438\u043f\u0430 kubernetes<\/p>\n<\/li>\n<li>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u043b\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 spring security (\u043e\u0434\u043d\u0430\u043a\u043e \u044f \u043d\u0430\u0441\u0442\u0430\u0438\u0432\u0430\u044e, \u0447\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u043d\u0438\u0436\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u043f\u043e\u043b\u043d\u0435 \u043d\u0430\u0434\u0451\u0436\u043d\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430. \u0422\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u0435\u0441\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u043b\u043e\u0442\u043d\u043e \u0441\u0435\u0442\u044c \u043d\u0430 \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441\u043f\u0440\u0438\u043d\u0433-\u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438, \u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u043b\u0435\u0437\u0442\u044c \u0441 \u043d\u0435\u0451 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f). \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u044d\u0442\u043e \u0434\u0438\u0441\u043a\u0443\u0441\u0441\u0438\u043e\u043d\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041e\u0442\u043a\u0430\u0437 \u043e\u0442 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043d\u0430 \u0441\u0432\u043e\u0439 \u0440\u0438\u0441\u043a \u0438 \u0441\u0442\u0440\u0430\u0445 \u0438 \u0432\u0441\u0451 \u0442\u0430\u043a\u043e\u0435.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0439. \u041f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u0432\u0435\u0437\u0434\u0435 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0434\u0443\u043c\u0447\u0438\u0432\u043e\u0433\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u043c.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043d\u043e\u0433\u043e\u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u0439 gradle-\u043f\u0440\u043e\u0435\u043a\u0442<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c \u0442\u0435\u043e\u0440\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u0434\u043b\u0435-\u043f\u0440\u0435\u043e\u043a\u0442\u043e\u0432 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 <a href=\"https:\/\/www.book2s.com\/tutorials\/gradle-dependency-management.html\" rel=\"noopener noreferrer nofollow\">https:\/\/www.book2s.com\/tutorials\/gradle-dependency-management.html<\/a><\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u043e\u043c\u043e\u043b\u044f\u0441\u044c <a href=\"https:\/\/internat.msu.ru\/about\/istoriya\/kolmogorov\/\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043b\u043c\u043e\u0433\u043e\u0440\u043e\u0432\u0443 <\/a>\u0438 <a href=\"https:\/\/habr.com\/ru\/companies\/ua-hosting\/articles\/370259\/\" rel=\"noopener noreferrer nofollow\">\u0413\u043b\u0443\u0448\u043a\u043e<\/a>, \u043d\u0430\u0447\u043d\u0451\u043c \u043f\u043e\u0442\u0438\u0445\u043e\u043d\u044c\u043a\u0443<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043c\u0443\u043b\u044c\u0442\u0438\u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 SimpleSpring<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0444\u0430\u0439\u043b\u044b <\/p>\n<p><strong>settings.gradle<\/strong> &#8212; \u0432 \u043d\u0451\u043c \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043d\u0430\u0448\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043d\u0430\u0448\u0435\u0433\u043e &#171;\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e&#187; \u043f\u0440\u043e\u0435\u043a\u0442\u0430<br \/>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0442\u0443\u0434\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u0447\u043a\u0443 &#8212; \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 &#171;\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e&#187; \u043f\u0440\u043e\u0435\u043a\u0442\u0430<br \/><em>rootProject.name = &#8216;SpringSimple&#8217;<\/p>\n<p><\/em>\u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0430\u0439\u043b <strong>build.gradle<\/strong> &#8212; \u0432 \u043d\u0451\u043c \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438<\/p>\n<details class=\"spoiler\">\n<summary>\u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 build.gradle<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">\/*\u0423\u043a\u0430\u0436\u0435\u043c \u043a\u0430\u043a\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c (\u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b, \u043d\u043e \u043d\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b)*\/ plugins {     id 'java'     id 'org.springframework.boot' version '3.3.1'     id 'io.spring.dependency-management' version '1.1.5'     id 'org.openapi.generator' version '7.10.0' }  \/*\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044e\u0449\u0443\u044e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u0415\u0441\u043b\u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e, \u0442\u043e \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043d\u0438\u0436\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 lombok*\/ configurations {     compileOnly {         extendsFrom annotationProcessor     } }  \/*\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438, \u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0442\u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u0430\u0447\u0435\u043d\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0417\u0434\u0435\u0441\u044c \u0443\u043a\u0430\u0437\u0430\u043d \u043e\u0431\u0449\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439.*\/ repositories {     mavenCentral() }  \/*\u0412 \u044d\u0442\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u044b. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u0441\u0451, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u043e \u043a \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u0435\u043c \u0447\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0415\u0413\u041e \u043b\u0438\u0447\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 build.gradle.*\/ subprojects {     \/*\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u0442\u0440\u0438 \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u0441\u043a\u0430\u0447\u0435\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432.   \u041f\u043e\u0447\u0435\u043c\u0443 \u043d\u0435 \u0432\u0441\u0435 \u0447\u0435\u0442\u044b\u0440\u0435 \u0441\u0440\u0430\u0437\u0443? \u041f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0447\u0435\u0442\u0432\u0451\u0440\u0442\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d \u043d\u0443\u0436\u0435\u043d \u043d\u0435 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0435.   \u0422\u0430\u043c \u0433\u0434\u0435 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043d\u0443\u0436\u0435\u043d, \u043c\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u0435\u0433\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e.*\/     apply plugin: 'java'     apply plugin: 'org.springframework.boot'     apply plugin: 'io.spring.dependency-management'      \/*\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 (\u043a\u0440\u043e\u043c\u0435 \u043e\u0431\u0449\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0448\u0435). \u041d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \"\u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439\", \u0442\u043e \u0435\u0441\u0442\u044c \u0432\u0441\u0435 jar-\u0444\u0430\u0439\u043b\u044b \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0432 \u043f\u0430\u043f\u043a\u0443 libs \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0430       \u0417\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e? \u041d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043d\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u044f \u0435\u0451 \u0438\u0437 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f*\/     repositories {         mavenCentral()         flatDir {             dirs 'libs'         }     }      \/*\u041e\u0431\u044a\u044f\u0432\u0438\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041d\u0430\u043f\u043e\u043c\u043d\u0438\u044e \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0442\u0430\u043a \u043a\u0430\u043a \u0443\u0430\u0437\u0430\u043d\u044b \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438 subprojects*\/     dependencies {         \/\/\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 PostConstructor         implementation 'javax.annotation:javax.annotation-api:1.3.2'          \/\/\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 jwt-\u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438.          implementation 'com.auth0:java-jwt:3.18.2'          \/\/\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u043e\u0432\u0430\u043d\u0438\u044f spring actuator \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c  https:\/\/www.concretepage.com\/spring-boot\/spring-boot-actuator-endpoints, https:\/\/www.book2s.com\/tutorials\/spring-boot-actuator.html         \/*\u0415\u0441\u043b\u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e, \u0442\u043e spring actuator \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0435 \u0430\u043f\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u043c\u0440\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438*\/                   implementation 'org.springframework.boot:spring-boot-starter-actuator'          \/\/spring admin client         \/\/\u041a\u043b\u0438\u0435\u043d\u0442 \u043a \u0441\u0435\u0440\u0432\u0438\u0441\u0443 \u0441\u043f\u0440\u0438\u043d\u0433-\u0431\u0443\u0442-\u0430\u0434\u043c\u0438\u043d \u0430\u043a\u043a\u0430\u043c\u0443\u043b\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u0443\u044e \u0438\u043c \u0447\u0435\u0440\u0435\u0437 spring actuator         implementation 'de.codecentric:spring-boot-admin-starter-client:3.1.5'          \/\/swagger         \/\/\u041e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0438\u0436\u0435         implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0' \/\/\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c https:\/\/www.baeldung.com\/spring-rest-openapi-documentation          \/\/spring cloud config         \/\/\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0441 \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0422\u043e \u0435\u0441\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442 \u043a \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0438\u0441\u0443         implementation 'org.springframework.cloud:spring-cloud-starter-config'         implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'          \/\/lombok         \/*\u041a\u0440\u0430\u0439\u043d\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441\u0438\u043b\u044c\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0448\u0430\u044e\u0449\u0430\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430 \u043f\u0443\u0442\u0451\u043c \u0430\u0432\u0442\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u043e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f\u043c.           \u0418\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0439 \u0442\u0440\u0435\u0431\u0443\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u0435\u0440\u0435\u0434 \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0435\u0439*\/         compileOnly 'org.projectlombok:lombok:1.18.30'         annotationProcessor 'org.projectlombok:lombok:1.18.30'         testCompileOnly 'org.projectlombok:lombok'         testAnnotationProcessor 'org.projectlombok:lombok'     }     \/\/\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c (\u0438 \u0437\u0430\u0442\u0435\u043c \u0438\u0441\u043f\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438) \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u0441\u043f\u0440\u0438\u043d\u0433\u043e\u0432\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438     ext {         set('springCloudVersion', \"2023.0.1\")     }     dependencyManagement {         imports {             mavenBom \"org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}\"         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u044d\u0442\u043e\u0433\u043e \u0443\u0436\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. <br \/>\u041e\u0442\u043a\u0440\u043e\u0435\u043c \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 \u0441\u0440\u0435\u0434\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 IntelliJ IDEA (\u0434\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0434\u0435\u044f) \u0438 \u043e\u043d\u0430, \u043f\u043e\u043d\u044f\u0432 \u0447\u0442\u043e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0433\u0440\u0430\u0434\u043b\u0435-\u043f\u0440\u043e\u0435\u043a\u0442, \u0441\u0430\u043c\u0430 \u0441\u043a\u0430\u0447\u0430\u0435\u0442 \u0433\u0440\u0430\u0434\u043b\u0435-\u0432\u0440\u0430\u043f\u0435\u0440 \u0438 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<br \/>\u0427\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 (\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0433\u0440\u0430\u0434\u043b\u0435 \u0438 \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438) \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/www.book2s.com\/tutorials\/gradle-install.html\" rel=\"noopener noreferrer nofollow\">\u043c\u0430\u043d\u0443\u0430\u043b\u043e\u043c<\/a>.<\/p>\n<p>\u041e\u043f\u044f\u0442\u044c \u0436\u0435, \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0441\u043c \u0432\u043e\u0442 \u044d\u0442\u0443 <a href=\"https:\/\/www.book2s.com\/tutorials\/gradle-multi-project.html\" rel=\"noopener noreferrer nofollow\">\u0433\u043b\u0430\u0432\u0443 <\/a>\u043c\u0430\u043d\u0443\u0430\u043b\u0430<\/p>\n<details class=\"spoiler\">\n<summary>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0447\u0442\u043e\u0431\u044b \u043e\u0434\u043d\u0438 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441\u0430\u043c \u0431\u044b\u043b \u0431\u044b \u043c\u043d\u043e\u0433\u043e\u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c. \u0418\u043b\u0438 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0448\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432 \u0433\u0440\u0443\u043f\u043f\u0443?<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fd4\/55a\/821\/fd455a821efc9d37a768e76a1b669c54.png\" width=\"1872\" height=\"572\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fd4\/55a\/821\/fd455a821efc9d37a768e76a1b669c54.png\"\/><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u0435\u0440\u0432\u0438\u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 (SpringCloudConfig)<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0432\u0441\u0435\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u0433\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u043e\u043f\u0440\u043e\u0441\u044f\u0442.<\/p>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0434\u0435\u0441\u044c:<br \/><a href=\"https:\/\/sysout.ru\/spring-cloud-configuration-server\/\" rel=\"noopener noreferrer nofollow\">https:\/\/sysout.ru\/spring-cloud-configuration-server\/<\/a><br \/><a href=\"https:\/\/www.czetsuyatech.com\/2019\/10\/spring-config-using-git.html\" rel=\"noopener noreferrer nofollow\">https:\/\/www.czetsuyatech.com\/2019\/10\/spring-config-using-git.html<\/a><br \/><a href=\"https:\/\/docs.spring.io\/spring-cloud-config\/docs\/current\/reference\/html\/\" rel=\"noopener noreferrer nofollow\">https:\/\/docs.spring.io\/spring-cloud-config\/docs\/current\/reference\/html\/<\/a><br \/><a href=\"https:\/\/www.baeldung.com\/spring-cloud-config-without-git\" rel=\"noopener noreferrer nofollow\">https:\/\/www.baeldung.com\/spring-cloud-config-without-git<\/a><\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0441\u0438\u0432 \u0443\u0434\u0430\u0447\u0438 \u0443 <a href=\"https:\/\/ru.ruwiki.ru\/wiki\/%D0%91%D1%80%D1%83%D0%B4%D0%BD%D0%BE,_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80_%D0%9B%D1%8C%D0%B2%D0%BE%D0%B2%D0%B8%D1%87\" rel=\"noopener noreferrer nofollow\">\u0411\u0440\u0443\u0434\u043d\u043e <\/a>\u043f\u0440\u0438\u043c\u0435\u043c\u0441\u044f \u0437\u0430 \u0434\u0435\u043b\u043e<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 SpringCloudConfig \u0432\u043d\u0443\u0442\u0440\u0438 SpringSimple \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043d\u0438\u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435<\/p>\n<p>SpringSimple\/<br \/> \u2502<br \/> \u251c\u2500\u2500 build.gradle<br \/> \u251c\u2500\u2500 settings.gradle<br \/> \u2502<br \/> \u251c\u2500\u2500 SpringCloudConfig\/<br \/> \u2502   \u251c\u2500\u2500 build.gradle<br \/> \u2502   \u251c\u2500\u2500 git-local-repo\/<br \/> \u2502   \u2502         \u251c\u2500\u2500 * (\u043a\u0443\u0441\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432)<br \/> \u2502   \u2514\u2500\u2500 src\/<br \/> \u2502       \u251c\u2500\u2500 main\/<br \/> \u2502       \u2502     \u251c\u2500\u2500 java\/<br \/> \u2502       \u2502     \u2502    \u251c\u2500\u2500 ru\/<br \/> \u2502       \u2502     \u2502    \u2502    \u251c\u2500\u2500 configs\/<br \/> \u2502       \u2502     \u2502    \u2502    \u2502    \u251c\u2500\u2500 SpringCloudConfig.java<br \/> \u2502       \u2502     \u251c\u2500\u2500 resources\/<br \/> \u2502       \u2502     \u2502     \u251c\u2500\u2500application.properties<br \/> \u2502       \u2514\u2500\u2500 test\/<\/p>\n<p>\u0433\u0434\u0435 git-local-repo &#8212; \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0433\u0438\u0442-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 (\u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433) \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u043a\u0443\u0441\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0448 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 \u0444\u0430\u0439\u043b SpringSimple\\settings.gradle \u043a\u0430\u043a <em>include &#8216;SpringCloudConfig&#8217;<\/em> <\/p>\n<details class=\"spoiler\">\n<summary>build.gradle<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0417\u0434\u0435\u0441\u044c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (\u043f\u043e\u043c\u043d\u0438\u043c \u0447\u0442\u043e \u043a \u043d\u0438\u043c \u0434\u043e\u0431\u0430\u0432\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (SimpleSpring\\build.gradle))<\/p>\n<pre><code class=\"java\">\/\/\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0438 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 jar-\u0444\u0430\u0439\u043b\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 group = 'ru.configs' version = '1.0-SNAPSHOT'  dependencies {     \/\/\u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u043d\u0443 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \"\u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440\"     implementation 'org.springframework.cloud:spring-cloud-config-server' }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>SpringCloudConfig.java<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.configs;  import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer;  @SpringBootApplication \/*\u0412\u043e\u0442 \u044d\u0442\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f (EnableConfigServer) \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u0442 \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440*\/ @EnableConfigServer public class SpringCloudConfig {     public static void main(String[] args) {         SpringApplication.run(SpringCloudConfig.class, args);     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 application.properties \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435<\/p>\n<\/div>\n<\/details>\n<p>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u0441\u043f\u0440\u0438\u043d\u0433 \u0443\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u043b \u0432\u0441\u0451 \u0437\u0430 \u043d\u0430\u0441. \u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<details class=\"spoiler\">\n<summary>application.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">#\u0438\u043c\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f spring.application.name=SpringCloudConfig  # \u041f\u043e\u0440\u0442 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 server.port = 8888  # \u0443\u0440\u043b \u0441\u043f\u0440\u0438\u043d\u0433-\u0431\u0443\u0442-\u0430\u0434\u043c\u0438\u043d \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043a\u0443\u0434\u0430 \u0434\u0430\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043e \u0441\u0432\u043e\u0451\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 spring.boot.admin.client.url=http:\/\/localhost:8099  # \u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Git-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f #\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Config Server \u043c\u043e\u0436\u043d\u043e  \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f\u043c \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 http:\/\/localhost:8888\/{applicationName}\/{profile} #http:\/\/localhost:8888\/application\/default   \u0437\u0434\u0435\u0441\u044c application \u2014 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 (\u0431\u0435\u0437 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f), default \u2014 \u0438\u043c\u044f \u043f\u0440\u043e\u0444\u0438\u043b\u044f (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e default). #remoute # spring.cloud.config.server.git.uri=https:\/\/github.com\/myluckagain\/config.git # \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u043c #spring.cloud.config.server.git.cloneOnStart=true #local #spring.cloud.config.server.git.uri=d:\\\\Work\\\\Project\\\\SpringSimple\\\\SpringSimple\\\\SpringCloudConfig\\\\git-local-repo  #\u0447\u0442\u043e\u0431\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0443 \u0441\u0435\u0431\u044f \u0432 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0445 (resources\/config\/*) #spring.cloud.config.server.native.search-locations=classpath:\/config #spring.cloud.config.server.git.search-paths=config-server\/config  #\u0427\u0442\u043e\u0431\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0431\u0435\u0437 \u0433\u0438\u0442-\u0430 spring.profiles.active=native spring.cloud.config.server.native.search-locations=file:\/\/\/d:\\\\Work\\\\Project\\\\SpringSimple\\\\SpringSimple\\\\SpringCloudConfig\\\\git-local-repo <\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 \u0443 \u0441\u0435\u0431\u044f \u0433\u0438\u0442-\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0442\u043e \u0440\u0430\u0441\u043a\u043e\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0441\u0442\u0440\u043e\u0447\u043a\u0443 18, \u0430 \u0441\u0442\u0440\u043e\u043a\u0438 25 \u0438 26 \u0437\u0430\u043a\u043e\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0439\u0442\u0435. \u0412 \u0441\u0442\u0440\u043e\u043a\u0435 18 \u043f\u0440\u043e\u043f\u0438\u0448\u0438\u0442\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043a\u0443\u0441\u043a\u043e\u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0435\u0442\u0435 \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u043e\u0432\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0442\u043e \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0432 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 25 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u043e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041a\u0443\u0441\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u044d\u0442\u043e \u0444\u0430\u0439\u043b\u044b \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u0441\u043f\u0440\u0438\u043d\u0433-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u0445 .properties \u0438\u043b\u0438 .yml.<br \/>\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0435 \u043a \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0441\u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0442\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u044b \u043f\u043e \u0438\u0445 \u0438\u043c\u0435\u043d\u0438.<br \/>\u0418\u043c\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0430 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 application-\u0418\u043c\u044f\u041a\u043e\u043d\u0444\u0438\u0433\u0430.properties.<\/p>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u0431\u0443\u0434\u0443\u0442<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/76e\/77c\/48f\/76e77c48f421d0f925bea94148b208d9.png\" width=\"450\" height=\"233\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/76e\/77c\/48f\/76e77c48f421d0f925bea94148b208d9.png\"\/><\/figure>\n<details class=\"spoiler\">\n<summary>application-actuator.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">#\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0430\u043a\u0442\u0443\u0430\u0442\u043e\u0440\u0430. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u044d\u043d\u0434\u043f\u043e\u0439\u043d\u044b \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u043e\u043f \u0438\u043d\u0444 \u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 #\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u0432\u0441\u0435 \u044d\u043d\u0434\u043f\u043e\u0439\u043d\u0442\u044b (.exposure.include=*) \u0442\u0430\u043a \u043a\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e \u0443\u043c\u043e\u043b\u0447 \u0437\u0430\u043a\u0440\u044b\u0442\u0430 #https:\/\/www.baeldung.com\/spring-boot-actuators management.endpoint.shutdown.enabled=true management.endpoints.web.exposure.include=* management.endpoint.health.show-details=always management.endpoint.health.group.custom.include=* management.endpoint.health.group.custom.show-components=always management.endpoint.health.group.custom.show-details=always<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application-adminClient.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">#\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0441\u043f\u0440\u0438\u043d\u0433-\u0431\u0443\u0442-\u0430\u0434\u043c\u0438\u043d \u0441\u0435\u0440\u0432\u0435\u0440\u0443. #\u0437\u0434\u0435\u0441\u044c \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u043c \u044d\u043d\u0434\u043f\u043e\u0439\u043d\u0442\u0430\u043c, #\u043d\u043e \u043d\u0430\u043c \u044d\u0442\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u0437\u043e\u043d\u0435 spring.boot.admin.client.url=http:\/\/localhost:8099<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application-authSecret.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">#\u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043f\u0430\u0440\u043e\u043b\u0438 \u0434\u043b\u044f \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f\/\u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 #\u043f\u043e \u0445\u043e\u0440\u043e\u0448\u0435\u043c\u0443 \u0434\u043e\u043b\u0436\u043d\u044b \u043b\u0438\u0431\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0432 vault-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043b\u0438\u0431\u043e \u0437\u0430\u0434\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f #\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445 \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0432\u0438\u0434\u0435 - \u043f\u043b\u043e\u0445\u0430\u044f \u0438\u0434\u0435\u044f auth.jwt.secret.access=super-secret-key- auth.jwt.secret.refresh=super-secret-key-<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application-AuthService.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>#\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u0439\u043e\u043a\u0438 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 #\u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0431\u0434 \u0433\u0434\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0445\u044d\u0448\u0438 \u0438\u0445 \u043f\u0430\u0440\u043e\u043b\u0435\u0439  #h2 db spring.datasource.url: jdbc:h2:~\/MYDB1;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE;AUTO_SERVER=TRUE #spring.datasource.url: jdbc:h2:mem:MYDB;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE spring.datasource.driverClassName: org.h2.Driver spring.datasource.username: sa spring.datasource.password: spring.jpa.database-platform: org.hibernate.dialect.H2Dialect #http:\/\/localhost:8080\/h2-console spring.h2.console.enabled=true<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432\u044b \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0432\u0435\u0431-\u043a\u043e\u043d\u0441\u043e\u043b\u0438  h2-\u0431\u0434 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application-ext.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>#\u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0438\u0436\u0435 \u043f\u043e\u043a\u0430\u0436\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f myValue=ttttt2<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application-hibernate.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>#\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 hibernate  # \u0412\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0431\u0434. \u041e spring.datasource.initialization-mode=never spring.jpa.defer-datasource-initialization = false spring.sql.init.mode = never  #\u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0443 \u043f\u043e \u0443\u043c\u043e\u0447\u0430\u043d\u0438\u044e spring.datasource.sql-script-encoding= UTF-8 spring.sql.init.encoding = UTF-8  # \u0415\u0441\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0430 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0432\u043e\u0430\u043d\u043d\u044b\u0445 hiberate sql-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0442\u043e \u0440\u0430\u0441\u0441\u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0442\u0435 \u0441\u0442\u0440\u043e\u0447\u043a\u0438 \u043d\u0438\u0436\u0435 #spring.jpa.show-sql=true #spring.jpa.properties.hibernate.format_sql=true #logging.level.org.hibernate.SQL=DEBUG #logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE  #\u0432\u043a\u043b\u044e\u0447\u0438\u043c \u043b\u0435\u043d\u0438\u0432\u0443\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u0422\u043e \u0435\u0441\u0442\u044c \u0445\u0438\u0431\u0435\u0440\u043d\u0435\u0439\u0442 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043a\u0430 \u043e\u043d\u0438 \u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true  #\u0434\u0430\u0434\u0438\u043c \u0445\u0438\u0431\u0435\u0440\u043d\u0435\u0439\u0442\u0443 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c (\u0438\u043b\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0442\u044c) \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0431\u0434 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c spring.jpa.hibernate.ddl-auto=update<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application-swagger.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">#swagger #http:\/\/localhost:8080\/api-docs #http:\/\/localhost:8080\/api-docs.yaml #http:\/\/localhost:8080\/swagger-ui\/index.html springdoc.api-docs.enabled=true springdoc.swagger-ui.enabled=true springdoc.swagger-ui.path=swagger-ui.html springdoc.api-docs.path=\/api-docs<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application-WebApplication1.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">#\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f WebApplication  #\u0435\u0441\u043b\u0438 \u0438\u0441\u0442\u0438\u043d\u0430, \u0442\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430, \u0438\u043d\u0430\u0447\u0435 - \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0430 auth.enabled=true  # inout answer on ResponseStatusException server.error.include-message=always  #h2 db #spring.datasource.url: jdbc:h2:~\/MYDB;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE;AUTO_SERVER=TRUE spring.datasource.url: jdbc:h2:mem:MYDB;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE spring.datasource.driverClassName: org.h2.Driver spring.datasource.username: sa spring.datasource.password: spring.jpa.database-platform: org.hibernate.dialect.H2Dialect #http:\/\/localhost:8080\/h2-console spring.h2.console.enabled=true  ## MULTIPART (MultipartProperties) # Enable multipart uploads spring.servlet.multipart.enabled=true # Threshold after which files are written to disk. spring.servlet.multipart.file-size-threshold=2KB # Max file size. spring.servlet.multipart.max-file-size=200MB # Max Request Size spring.servlet.multipart.max-request-size=215MB<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application-WebSecurityApplication.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>#\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f WebSecurityApplication  #\u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u043b\u044f \u0441\u043f\u0440\u0438\u043d\u0433-\u0441\u0435\u0440\u043a\u044c\u044e\u0442\u0440\u0438\u0442\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0430\u0440\u043e\u043b\u044c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. \u041d\u0438\u0433\u0434\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 spring.security.user.name=u2 spring.security.user.password=p2<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041a\u0430\u043a \u0438 \u043b\u044e\u0431\u043e\u0439 \u0433\u0440\u0430\u0434\u043b\u0435 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u0441\u043f\u0440\u0438\u043d\u0433-\u0431\u0443\u0442\u0435, \u043e\u043d \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0442\u0430\u0441\u043a\u0443 boot-Run, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/35c\/5ba\/320\/35c5ba32032853378a094ad53db5dc7a.png\" width=\"405\" height=\"474\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/35c\/5ba\/320\/35c5ba32032853378a094ad53db5dc7a.png\"\/><\/figure>\n<p>\u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 \u043b\u043e\u0433\u0430\u0445 \u043e\u0448\u0438\u0431\u043a\u0443 \u0432\u0438\u0434\u0430 &#171;Failed to register application as Application&#187; \u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0443\u044e \u0447\u0442\u043e \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0435 \u0441\u043c\u043e\u0433 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0441\u043f\u0440\u0438\u043d\u0433-\u0431\u0443\u0442-\u0430\u0434\u043c\u0438\u043d-\u0441\u0435\u0440\u0432\u0435\u0440\u0443 (\u043a\u0430\u043a \u043c\u044b \u044d\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 application.properties).<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0447\u0435\u0440\u0435\u0437 <a href=\"http:\/\/localhost:8888\/application\/default\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:8888\/application\/default<\/a> \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e (\u0442\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0430 git-local-repo\\application.properties)<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d7c\/19b\/c9d\/d7c19bc9d3a22e9f1a013271d0d21009.png\" width=\"334\" height=\"218\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d7c\/19b\/c9d\/d7c19bc9d3a22e9f1a013271d0d21009.png\"\/><\/figure>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433 \u0434\u043b\u044f \u043f\u0440\u043e\u0444\u0438\u043b\u044f ext <a href=\"http:\/\/localhost:8888\/application\/ext\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:8888\/application\/ext<\/a> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0435\u0433\u043e<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/824\/5d7\/711\/8245d7711c730d49483aacdcba8bac8d.png\" width=\"796\" height=\"339\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/824\/5d7\/711\/8245d7711c730d49483aacdcba8bac8d.png\"\/><\/figure>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0441\u0440\u0430\u0437\u0443 \u0434\u043b\u044f \u0434\u0432\u0443\u0445 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 ext \u0438 actuator \u043a\u0430\u043a <a href=\"http:\/\/localhost:8888\/application\/ext,%20actuator\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:8888\/application\/ext, actuator<\/a> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0438\u0445<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/309\/619\/450\/309619450876dfe25405446ab47a1780.png\" width=\"829\" height=\"471\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/309\/619\/450\/309619450876dfe25405446ab47a1780.png\"\/><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442: \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440 \u0441\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0444\u0438\u0433 \u0432 \u0441\u043e\u043e\u0442\u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 (\u0435\u0441\u043b\u0438 \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043f\u0430\u043f\u043a\u0443) \u0438\u043b\u0438 \u0437\u0430\u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0433\u0438\u0442 (\u0435\u0441\u043b\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0433\u0438\u0442) \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0442\u0443\u043f\u0438\u043b\u0438 \u0432 \u0441\u0438\u043b\u0443. \u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u0435\u0440\u0432\u0438\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 (AuthService) <\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u043f\u0440\u043e\u0441\u0438\u0432 \u0443\u0434\u0430\u0447\u0438 \u0443 <a href=\"https:\/\/habr.com\/ru\/companies\/ua-hosting\/articles\/388169\/\" rel=\"noopener noreferrer nofollow\">\u041b\u0435\u0431\u0435\u0434\u0435\u0432\u0430<\/a>, \u043d\u0430\u0447\u043d\u0451\u043c \u043f\u043e\u0442\u0438\u0445\u043e\u043d\u044c\u043a\u0443.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 AuthService \u0432\u043d\u0443\u0442\u0440\u0438 SpringSimple \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043d\u0438\u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435<\/p>\n<p>SpringSimple\/<br \/> \u2502<br \/> \u251c\u2500\u2500 build.gradle<br \/> \u251c\u2500\u2500 settings.gradle<br \/> \u2502<br \/> \u251c\u2500\u2500 AuthService\/<br \/> \u2502   \u251c\u2500\u2500 build.gradle<br \/> \u2502   \u2514\u2500\u2500 src\/<br \/> \u2502       \u251c\u2500\u2500 main\/<br \/> \u2502       \u2502     \u251c\u2500\u2500 java\/<br \/> \u2502       \u2502     \u2502    \u251c\u2500\u2500 ru\/<br \/> \u2502       \u2502     \u2502    \u2502    \u251c\u2500\u2500 auth\/<br \/> \u2502       \u2502     \u2502    \u2502    \u2502    \u251c\u2500\u2500 AuthService.java<br \/> \u2502       \u2502     \u251c\u2500\u2500 resources\/<br \/> \u2502       \u2502     \u2502     \u251c\u2500\u2500application.properties<br \/> \u2502       \u2514\u2500\u2500 test\/<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 AuthService.java<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.auth;  import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;  @SpringBootApplication public class AuthService {     public static void main(String[] args) {         SpringApplication.run(AuthService.class, args);     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>build.gradle<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u044e\u0434\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041d\u0430\u043f\u043e\u043c\u043d\u044e \u0447\u0442\u043e \u043e\u043d\u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c\u0441\u044f \u0441 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 SpringSimple\\build.gradle \u0438\u0437 \u0441\u0435\u043a\u0446\u0438\u0438 subproject<\/p>\n<pre><code class=\"java\">group = 'ru.auth' version = '1.0-SNAPSHOT'  dependencies {     \/\/spring     implementation 'org.springframework.boot:spring-boot-starter-data-jpa'     implementation 'org.springframework.boot:spring-boot-starter-web'      \/\/db     runtimeOnly 'com.h2database:h2'     testImplementation 'com.h2database:h2:2.2.224'      \/\/Bcrypt. \u0414\u043b\u044f \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u043e\u043b\u044f \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u043e \u0445\u044d\u0448\u0443     implementation group: 'org.mindrot', name: 'jbcrypt', version: '0.4' }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">spring.application.name=AuthService server.port=8079  #config spring.profiles.active=authSecret, swagger, AuthService, hibernate, adminClient, actuator spring.cloud.config.fail-fast=true spring.cloud.config.uri=http:\/\/localhost:8888 spring.config.import=optional:configserver:http:\/\/localhost:8888 spring.cloud.config.import-check.enabled=true  <\/code><\/pre>\n<p>\u0432 \u0441\u0442\u0440\u043e\u043a\u0435 5 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u043c  \u043f\u0440\u043e\u0444\u0438\u043b\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442 \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440\u0430.<br \/>\u041d\u0438\u0436\u0435 \u0438\u0434\u0443\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440\u0443<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 SpringSimple\\settings.gradle \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043d\u0430\u0448 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043a\u0430\u043a<br \/>include &#8216;AuthService&#8217; <\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438 \u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 OAuth 2.0<\/summary>\n<div class=\"spoiler__content\">\n<p>OAuth 2.0\u00a0\u2014 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0432\u044b\u0434\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u043c\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0443 (\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e) \u043f\u0440\u0430\u0432\u0430 \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0435. \u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043b\u043e\u0433\u0438\u043d \u0438 \u043f\u0430\u0440\u043e\u043b\u044c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0430\u0432, \u0430 \u043d\u0435 \u0432\u0441\u0435 \u0441\u0440\u0430\u0437\u0443.<\/p>\n<p>\u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c JWT \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043f\u0435\u0440\u0435\u043b\u043e\u0436\u0438\u0432 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b.<\/p>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 \u0430\u0443\u0442\u0438\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u2014 \u0437\u0430 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443. \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b, \u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0445 \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c. <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e.<\/p>\n<ol>\n<li>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u0441 \u043b\u043e\u0433\u0438\u043d\u043e\u043c \u0438 \u043f\u0430\u0440\u043e\u043b\u0435\u043c. \u041a\u043b\u0438\u0435\u043d\u0442 (\u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434) \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u043c \u043b\u043e\u0433\u0438\u043d \u0438 \u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<br \/>\u0412 \u043e\u0442\u0432\u0435\u0442 \u043e\u043d \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0430\u0440\u0443 \u0442\u043e\u043a\u0435\u043d\u043e\u0432: access \u0438 refresh<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 access-\u0442\u043e\u043a\u0435\u043d\u0430. \u041a\u043b\u0438\u0435\u043d\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 access-\u0442\u043e\u043a\u0435\u043d \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 API \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 access-\u0442\u043e\u043a\u0435\u043d\u0430. \u0412\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442: \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 access-\u0442\u043e\u043a\u0435\u043d\u0430 \u043e\u0447\u0435\u043d\u044c \u043c\u0430\u043b\u043e. \u041e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043f\u044f\u0442\u0438 \u043c\u0438\u043d\u0443\u0442, \u043a\u043e\u0433\u0434\u0430 \u0441\u0440\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f access-\u0442\u043e\u043a\u0435\u043d\u0430 \u0438\u0441\u0442\u0435\u043a\u0430\u0435\u0442, \u043a\u043b\u0438\u0435\u043d\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 refresh-\u0442\u043e\u043a\u0435\u043d \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 access-\u0442\u043e\u043a\u0435\u043d. \u042d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0438\u0441\u0442\u0435\u0447\u0451\u0442 \u0441\u0440\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f refresh-\u0442\u043e\u043a\u0435\u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u0435\u043b\u0438\u043a \u0438 \u043c\u043e\u0436\u0435\u0442 \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0442\u044c 30 \u0434\u043d\u0435\u0439.<br \/>\u0414\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0430\u043c\u043e\u0433\u043e refresh-\u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440-\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c (\u0435\u0449\u0451 \u043d\u0435 \u0438\u0441\u0442\u0451\u043a\u0448\u0438\u043c) access-\u0442\u043e\u043a\u0435\u043d\u043e\u043c \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u044b\u043c refresh-\u0442\u043e\u043a\u0435\u043d\u043e\u043c. \u0412 \u043e\u0442\u0432\u0435\u0442 \u043f\u0440\u0438\u0434\u0451\u0442 \u043d\u043e\u0432\u044b\u0439 refresh-\u0442\u043e\u043a\u0435\u043d. \u0418\u043b\u0438 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043d\u043e\u0432\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u043b\u043e\u0433\u0438\u043d\u043e\u043c \u0438 \u043f\u0430\u0440\u043e\u043b\u0435\u043c \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0439 \u043f\u0430\u0440\u044b \u0442\u043e\u043a\u0435\u043d\u043e\u0432<\/p>\n<\/li>\n<\/ol>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fd0\/7d7\/c98\/fd07d7c98f4f5f0371dc8a9d685053ff.png\" width=\"427\" height=\"375\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fd0\/7d7\/c98\/fd07d7c98f4f5f0371dc8a9d685053ff.png\"\/><\/figure>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043c<br \/><a href=\"https:\/\/struchkov.dev\/blog\/ru\/jwt-implementation-in-spring\/\" rel=\"noopener noreferrer nofollow\">https:\/\/struchkov.dev\/blog\/ru\/jwt-implementation-in-spring\/<\/a> <br \/><a href=\"https:\/\/habr.com\/ru\/companies\/vk\/articles\/115163\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/companies\/vk\/articles\/115163\/<\/a><\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/summary>\n<div class=\"spoiler__content\">\n<details class=\"spoiler\">\n<summary>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u043e\u043a\u0435\u043d\u043e\u043c<\/summary>\n<div class=\"spoiler__content\">\n<details class=\"spoiler\">\n<summary>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 TokenService.java<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.auth.service;  import com.auth0.jwt.interfaces.DecodedJWT;  import java.util.List;  \/**\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f jwt-\u0442\u043e\u043a\u0435\u043d\u0430 \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430*\/ public interface TokenService {     String generateAccessToken(String clientId, String audience, String roles);     String generateRefreshToken(String clientId, String audience);      Boolean checkAccessToken(String accessToken);     Boolean checkRefreshToken(String refreshToken);     DecodedJWT decodeRefreshToken(String refreshToken);      } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>DefaultTokenService.java &#8212; \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.auth.service;  import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTVerificationException; import com.auth0.jwt.interfaces.DecodedJWT; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service;  import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.List;  @Service @Slf4j public class DefaultTokenService implements TokenService {     @Value(\"${auth.jwt.secret.access}\")     private String secretAccessKey;     @Value(\"${auth.jwt.secret.refresh}\")     private String secretRefreshKey;       \/**\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430      * @param clientId - \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u043e\u043a\u0435\u043d      * @param secretKey - \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u043c \u0435\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c      * @param minuts - \u0447\u0435\u0440\u0435\u0437 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0438\u043d\u0443\u0442 \u0438\u0441\u0442\u0435\u0447\u0451\u0442 \u0441\u0440\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u0430      * @param audience - \u0434\u043b\u044f \u043a\u0430\u043a\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u043e\u043a\u0435\u043d      * @param roles - \u0441\u043f\u0438\u0441\u043e\u043a \u0440\u043e\u043b\u0435\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0447\u0435\u0440\u0435 \u0437\u0430\u043f\u044f\u0442\u0443\u044e      * @return - \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d      *  *\/     private String generateToken(String clientId, String secretKey, Long minuts, String audience, String roles) {         Algorithm algorithm = Algorithm.HMAC256(secretKey);          Instant now = Instant.now();         Instant exp = now.plus(minuts, ChronoUnit.MINUTES);          return JWT.create()                 .withIssuer(\"auth-service\") \/\/\u043a\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043b \u0442\u043e\u043a\u0435\u043d                 .withClaim(\"roles\",roles)  \/\/\u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u0440\u043e\u043b\u044f\u043c\u0438                 .withAudience(audience) \/\/\u0434\u043b\u044f \u043a\u0430\u043a\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0441\u0435\u0440\u0432\u0438\u0441\u0430-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432)                 .withSubject(clientId) \/\/\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u041e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u043e \u0435\u0433\u043e \u043f\u043e\u0447\u0442\u0430 \u0438\u043b\u0438 \u043d\u043e\u043c\u0435\u0440 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430                 .withIssuedAt(Date.from(now))\/\/\u043a\u043e\u0433\u0434\u0430 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u0442\u043e\u043a\u0435\u043d                 .withExpiresAt(Date.from(exp)) \/\/\u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u0438\u0441\u0442\u0435\u0447\u0451\u0442                 .sign(algorithm);     }      @Override     public String generateAccessToken(String clientId, String audience, String roles) {         return generateToken(clientId, secretAccessKey, 5L, audience, roles);     }      @Override     public String generateRefreshToken(String clientId, String audience) {         return generateToken(clientId, secretRefreshKey, 666L, audience, null);     }       \/**\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430      * @param token - \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c\u044b\u0439 \u0442\u043e\u043a\u0435\u043d      * @param secretKey - \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u043d \u0431\u044b\u043b \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d      * @return - \u0438\u0441\u0442\u0438\u043d\u0430, \u0435\u0441\u043b\u0438 \u0442\u043e\u043a\u0435\u043d \u0432\u0430\u043b\u0438\u0434\u0435\u043d \u0438 \u043b\u043e\u0436\u044c \u0435\u0441\u043b\u0438 \u043d\u0435 \u0432\u0430\u043b\u0438\u0434\u0435\u043d*\/     private boolean checkToken(String token, String secretKey) {         Algorithm algorithm = Algorithm.HMAC256(secretKey);         JWTVerifier verifier = JWT.require(algorithm).build();          try {             DecodedJWT decodedJWT = verifier.verify(token);             return true;         } catch (JWTVerificationException e) {             log.error(\"Token is invalid: \" + e.getMessage());             return false;         }     }      \/**\u0414\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d      * @param refreshToken - \u0440\u0435\u0444\u0440\u0435\u0448-\u0442\u043e\u043a\u0435\u043d      * @return - \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u0438\u043b\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435*\/     @Override     public DecodedJWT decodeRefreshToken(String refreshToken) {         Algorithm algorithm = Algorithm.HMAC256(secretAccessKey);         JWTVerifier verifier = JWT.require(algorithm).build();         return verifier.verify(refreshToken);     }      @Override     public Boolean checkAccessToken(String accessToken) {         return checkToken(accessToken, secretAccessKey);     }      @Override     public Boolean checkRefreshToken(String refreshToken) {         return checkToken(refreshToken, secretRefreshKey);     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"https:\/\/jwt.io\/\" rel=\"noopener noreferrer nofollow\">https:\/\/jwt.io\/<\/a><\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432 \u0431\u0434 <\/summary>\n<div class=\"spoiler__content\">\n<p>\u0411\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c hibernate.<br \/>\u041f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 spring.jpa.hibernate.ddl-auto=update \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442 \u0445\u0438\u0431\u0435\u0440\u043d\u0435\u0439\u0442\u0443 \u0441\u0430\u043c\u043e\u043c\u0443 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c (\u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043d\u043e \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435)<\/p>\n<p>spring.datasource.url: jdbc:h2:~\/MYDB1;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE;AUTO_SERVER=TRUE<br \/>\u0414\u0430\u043d\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0447\u0442\u043e \u0431\u0430\u0437\u0430 h2 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 (\u0442\u043e \u0435\u0441\u0442\u044c \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f) \u0432 \u0444\u0430\u0439\u043b\u0435 MYDB1.<\/p>\n<details class=\"spoiler\">\n<summary>ClientEntity.java &#8212; \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.auth.db.entity;  import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;  @Data @NoArgsConstructor @AllArgsConstructor @Entity @Table(name = \"clients\", indexes = {         @Index(name = \"clientId_audience\", columnList = \"clientId, audience\", unique = true) \/\/\u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0438\u043d\u0434\u0435\u043a\u0441 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043f\u043e\u0438\u0441\u043a\u0430 }) \/**\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439*\/ public class ClientEntity {     @Id     @GeneratedValue(strategy = GenerationType.IDENTITY)     private Long id;      \/**\u0423\u0418\u0414-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438\u043b\u0438 \u0435\u0433\u043e \u043f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c*\/     private String clientId;      \/**\u0415\u0433\u043e \u0440\u043e\u043b\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0439 audience \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e*\/     private String roles;      \/**\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f \u043f\u043e\u0434 \u043d\u0443\u0436\u043d\u043e\u0439 \u0440\u043e\u043b\u044c\u044e*\/     private String audience;      \/**\u0425\u044d\u0448 \u0435\u0433\u043e \u043f\u0430\u0440\u043e\u043b\u044f*\/     private String hash; } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>ClientRepository.java &#8212; \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0432 \u0431\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.auth.db.repository;  import org.springframework.data.repository.CrudRepository; import ru.auth.db.entity.ClientEntity;  import java.util.Optional;  public interface ClientRepository extends CrudRepository&lt;ClientEntity, String&gt; {     Optional&lt;ClientEntity&gt; findByClientIdAndAudience(String clientId, String audience); \/\/\u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u0440\u0430\u0437\u0432\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0431\u0434 \u043a\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0433\u0435\u043d\u0435\u043d\u0440\u0438\u0440\u0443\u0435\u0442 \u0445\u0438\u0431\u0435\u0440\u043d\u0435\u0439\u0442 \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433 WebConfig.java \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043b\u043e\u0432\u0438\u0442\u044c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 CORS-\u043e\u0448\u0438\u0431\u043a\u0443 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u0432\u0430\u0433\u0433\u0435\u0440\u0430 \u0447\u0435\u0440\u0435\u0437 \u0433\u0435\u0439\u0442\u0432\u0435\u0439<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.auth.config;  import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  \/\/https:\/\/www.baeldung.com\/spring-cors \/**\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u043c CORS-\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u044d\u0442\u043e\u0442 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440 \u0447\u0442\u043e\u0431\u044b \u0441\u0432\u0430\u0433\u0433\u0435\u0440 \u0441 \u0448\u043b\u044e\u0437\u0430 \u043c\u043e\u0433 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0441\u044e\u0434\u0430*\/ @Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer {      @Override     \/**\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c CORS \u0434\u043b\u044f \u0441\u0432\u0430\u0433\u0433\u0435\u0440\u0430*\/     public void addCorsMappings(CorsRegistry registry) {         registry.addMapping(\"\/**\");     } }<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u043d\u0444\u0438\u0433 \u043d\u0443\u0436\u0435\u043d \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438\u0437 \u0441\u0432\u0430\u0433\u0433\u0435\u0440\u0430 \u0448\u043b\u044e\u0437\u0430 (\u0433\u0435\u0439\u0442\u0432\u0435\u044f) \u043a \u0441\u0432\u0430\u0433\u0433\u0435\u0440\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435 \u043b\u043e\u0432\u0438\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443 &#171;\u043f\u043e\u0434\u043c\u0435\u043d\u044b&#187; \u0445\u043e\u0441\u0442\u0430 \u0438 \u043f\u043e\u0440\u0442\u0430.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u0440\u0430\u0442\u043a\u043e, \u0442\u043e \u0431\u0440\u0430\u0437\u0443\u0435\u0440\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u044e\u0442 CORS \u0442\u043e \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u043c\u0443 \u0431\u044d\u043a-\u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u043f\u0435\u0440\u0435\u0441\u044b\u043b\u0430\u0442\u044c (\u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443) \u0437\u0430\u043f\u0440\u043e\u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0431\u044d\u043a-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u043e\u0440\u0442\u043e\u043c \u0438\u043b\u0438 \u0445\u043e\u0441\u0442\u043e\u043c \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u0438 \u043e\u0442\u0432\u0438\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043e\u0442 \u0441\u0432\u043e\u0435\u0433\u043e \u043b\u0438\u0446\u0430.<br \/>CORS \u0437\u0430\u043f\u0440\u0435\u0449\u0451\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c \u043e\u0442 \u0441\u043e\u0432\u0441\u0435\u043c \u0433\u043b\u0443\u043f\u044b\u0445 \u043c\u043e\u0448\u0435\u043d\u043d\u0438\u043a\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043d\u0430\u0447\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0441\u0430\u0439\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0437\u0430\u0442\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0438\u0445 \u043d\u0430 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0442\u0440\u0430\u043d\u0441\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u043e\u0442\u0432\u0435\u0442\u044b \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0443.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>DTO &#8212; data transfer object. \u0422\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u0435\u0436\u0434\u0443 \u0444\u0440\u043e\u043d\u0442\u043e\u043c \u0438 \u0431\u044d\u043a\u043e\u043c, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438)<\/summary>\n<div class=\"spoiler__content\">\n<details class=\"spoiler\">\n<summary>AuthRequestDto.java<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.auth.api.dto;  import lombok.Value;  \/**\u0414\u0442\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0443 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438*\/ @Value public class AuthRequestDto {     String clientId;     String audience;     String clientSecret; } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>AuthResponseDto.java<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.auth.api.dto;  import lombok.*;  \/**\u0414\u0442\u043e \u0434\u043b\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0430\u043a\u0446\u0438\u0438*\/ @Value public class AuthResponseDto {     private final String type = \"Bearer\";     String accessToken;     String refreshToken; } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>ErrorResponseDto<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.auth.api.dto;  import lombok.Value;  \/**\u0414\u0442\u043e \u0434\u043b\u044f \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430*\/ @Value public class ErrorResponseDto {     String message; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>AuthController.java<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0430\u0448 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \/auth\/reg \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u042d\u0442\u043e \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u044b \u0438, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0430 \u043f\u0440\u043e\u0434-\u0441\u0442\u0435\u043d\u0434\u0435 \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u043b\u0435\u0436\u0430\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0432\u0435\u0431-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435, \u0431\u044b\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u0449\u0438\u0449\u0451\u043d\u043d\u044b\u043c, \u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u0430\u0436\u0435 \u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0432\u0441\u0435. \u0421 \u0442\u0435\u043c \u0436\u0435 \u0443\u0441\u043f\u0435\u0445\u043e\u043c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0441 \u0431\u0434, \u0442\u043e\u043b\u044c\u043a\u043e \u0445\u044d\u0448 \u043f\u0430\u0440\u043e\u043b\u0435\u0439 \u0438\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0440\u0443\u043a\u0430\u043c\u0438. \u041d\u0430\u043f\u043e\u043c\u043d\u044e \u0447\u0442\u043e \u043f\u0430\u0440\u043e\u043b\u0438 \u043d\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0432\u0438\u0434\u0435. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u0438\u0445 \u0445\u044d\u0448\u0438 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u044c \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u043e\u043b\u044f, \u043d\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0443\u0437\u043d\u0430\u0442\u044c \u0441\u0430\u043c \u043f\u0430\u0440\u043e\u043b\u044c.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <a class=\"mention\" href=\"\/users\/exceptionhandler\">@ExceptionHandler<\/a>\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0443\u044e \u0447\u0442\u043e \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0435\u044e \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u043b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0443\u043f\u0430\u0434\u0451\u0442 \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>\u0415\u0449\u0451 \u0432\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442: \u043f\u043e \u043f\u043b\u0430\u043d\u0443 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c brear-\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e. \u0422\u043e \u0435\u0441\u0442\u044c \u043d\u0430\u0448 \u0430ccess-\u0442\u043e\u043a\u0435\u043d \u043a\u043e\u0433\u0434\u0430 \u0444\u0440\u043e\u043d\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u043e\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435 http-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 Authorization.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9fc\/b2c\/a00\/9fcb2ca003001c0fd517b95ddd1d13b4.png\" alt=\"\u0432\u043e\u0442 \u0442\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 postman-e\" title=\"\u0432\u043e\u0442 \u0442\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 postman-e\" width=\"1121\" height=\"428\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9fc\/b2c\/a00\/9fcb2ca003001c0fd517b95ddd1d13b4.png\"\/><\/p>\n<div><figcaption>\u0432\u043e\u0442 \u0442\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 postman-e<\/figcaption><\/div>\n<\/figure>\n<p>\u042d\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u043d\u0430\u043c\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u043a\u043e\u0433\u0434\u0430 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0443\u0440\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0434\u0451\u0442 \u0434\u043e \u0433\u0435\u0439\u0442\u0432\u0435\u044f \u043f\u043e https.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 (\u0445\u043e\u0442\u044f \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u044f\u0432\u043d\u043e \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u043e) \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0442\u043e\u043a\u0435\u043d\u0430 cookie \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u043e\u0440\u043e\u0448\u0438 \u0442\u0435\u043c, \u0447\u0442\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440 (\u0442\u043e \u0435\u0441\u0442\u044c \u0444\u0440\u043e\u043d\u0442-\u043a\u043b\u0438\u0435\u043d\u0442) \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0438\u0445 \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u041d\u043e, \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0443-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u0436\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c-\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0434\u043b\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438 \u0430\u0446\u0435\u0441\u0441-\u0442\u043e\u043a\u0435\u043d\u0430.<br \/>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u044f\u0432\u043d\u043e \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u043e.<\/p>\n<pre><code class=\"java\">package ru.auth.api;  import com.auth0.jwt.interfaces.DecodedJWT; import lombok.RequiredArgsConstructor; import org.mindrot.jbcrypt.BCrypt; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import ru.auth.api.dto.AuthRequestDto; import ru.auth.api.dto.AuthResponseDto; import ru.auth.api.dto.ErrorResponseDto; import ru.auth.db.entity.ClientEntity; import ru.auth.db.repository.ClientRepository; import ru.auth.service.TokenService;  import javax.security.auth.login.LoginException; import java.util.Optional; import java.util.HashMap; import java.util.Map;  @RestController @RequestMapping(\"\/auth\") @RequiredArgsConstructor public class AuthController {      private final ClientRepository userRepository;     private final TokenService tokenService;     private final Map&lt;String, String&gt; refreshStorage = new HashMap&lt;&gt;(); \/\/\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0432\u044b\u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0435\u0444\u0440\u0435\u0448-\u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u0414\u043b\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0447\u0442\u043e \u043c\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0434\u0430\u0432\u0430\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d      \/**\u0421\u0435\u0440\u0432\u0438\u0441 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0430\u0434\u043c\u0438\u043d\u043e\u0432. \u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430      * @param clientId - \u043a\u043b\u0438\u0435\u043d\u0442      * @param clientSecret - \u043f\u0430\u0440\u043e\u043b\u044c,      * @param audience - \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0434\u0430\u0451\u043c \u043f\u0440\u0430\u0432\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0443      * @param roles - \u043f\u0440\u0430\u0432\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0430\u0451\u043c*\/     @PostMapping(\"\/reg\")     public void register(String clientId, String clientSecret, String audience, String roles) throws LoginException {         if(userRepository.findByClientIdAndAudience(clientId, audience).isPresent())             throw new LoginException(\"Client with id=\" + clientId+\" audience=\"+audience + \" already registered\");          String hash = BCrypt.hashpw(clientSecret, BCrypt.gensalt());         userRepository.save(new ClientEntity(null,clientId, roles, audience, hash));     }      \/**\u041b\u043e\u0433\u0438\u043d      * @param user - \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435      * @return - \u0430\u0446\u0435\u0441\u0441 \u0438 \u0440\u0435\u0444\u0440\u0435\u0448 \u0442\u043e\u043a\u0435\u043d\u044b*\/     @PostMapping(\"\/login\")     public AuthResponseDto login(@RequestBody AuthRequestDto user) throws LoginException{         checkCredentials(user.getClientId(), user.getClientSecret(), user.getAudience());         return generateNewAccessAndRefreshTokens(user.getClientId(), user.getAudience());     }      \/**\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0430\u0441\u0446\u0435\u0441\u0441 \u0442\u043e\u043a\u0435\u043d \u043f\u043e \u0440\u0435\u0444\u0440\u0435\u0448 \u0442\u043e\u043a\u0435\u043d\u0443      * @param refreshToken - \u0440\u0435\u0444\u0440\u0435\u0448 \u0442\u043e\u043a\u0435\u043d      * @return - \u043d\u043e\u0432\u044b\u0439 \u0430\u0446\u0435\u0441\u0441 \u0442\u043e\u043a\u0435\u043d*\/     @PostMapping(\"\/access\")     public AuthResponseDto getUpdateAccessToken(String refreshToken) throws LoginException{         if (tokenService.checkRefreshToken(refreshToken)){             DecodedJWT decodedJWT = tokenService.decodeRefreshToken(refreshToken);             String clientId=decodedJWT.getSubject();             String audience=decodedJWT.getAudience().get(0);             String savingRefreshToken = this.refreshStorage.get(clientId+\"-\"+audience);             if (!refreshToken.equals(savingRefreshToken))                 throw new LoginException(\"Refresh token not found\");              ClientEntity user=userRepository.findByClientIdAndAudience(clientId, audience).get();             return new AuthResponseDto(tokenService.generateAccessToken(user.getClientId(), user.getAudience(), user.getRoles()), null);         }         return new AuthResponseDto(null, null);     }     \/**\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0430\u0446\u0435\u0441\u0441 \u0438 \u0440\u0435\u0444\u0440\u0435\u0448 \u0442\u043e\u043a\u0435\u043d \u043f\u043e \u0440\u0435\u0444\u0440\u0435\u0448 \u0442\u043e\u043a\u0435\u043d\u0443      * @param refreshToken - \u0440\u0435\u0444\u0440\u0435\u0448 \u0442\u043e\u043a\u0435\u043d      * @return - \u0430\u0446\u0435\u0441\u0441 \u0438 \u0440\u0435\u0444\u0440\u0435\u0448 \u0442\u043e\u043a\u0435\u043d\u044b*\/     @PostMapping(\"\/refresh\")     public AuthResponseDto getUpdateAccessAndRefreshToken(String refreshToken) throws LoginException{         if (tokenService.checkRefreshToken(refreshToken)){             DecodedJWT decodedJWT = tokenService.decodeRefreshToken(refreshToken);             String clientId=decodedJWT.getSubject();             String audience=decodedJWT.getAudience().get(0);             String savingRefreshToken = this.refreshStorage.get(clientId+\"-\"+audience);             if (!refreshToken.equals(savingRefreshToken))                 throw new LoginException(\"Refresh token not found\");              return generateNewAccessAndRefreshTokens(clientId, audience);         }         return new AuthResponseDto(null, null);     }      @ExceptionHandler({LoginException.class})     public ResponseEntity&lt;ErrorResponseDto&gt; handleUserRegistrationException(Exception ex) {         return ResponseEntity                 .badRequest()                 .body(new ErrorResponseDto(ex.getMessage()));     }      \/**\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b      * @param clientId - \u043a\u043b\u0438\u0435\u043d\u0442      * @param clientSecret - \u043f\u0430\u0440\u043e\u043b\u044c      * @param audience - \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0434\u0430\u0451\u043c \u043f\u0440\u0430\u0432\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0443*\/     private void checkCredentials(String clientId, String clientSecret, String audience) throws LoginException {         Optional&lt;ClientEntity&gt; optionalUserEntity = userRepository.findByClientIdAndAudience(clientId, audience);         if (optionalUserEntity.isEmpty())             throw new LoginException(\"Client with id=\" + clientId+\" and audience=\"+audience + \" not found\");          ClientEntity clientEntity = optionalUserEntity.get();         if (!BCrypt.checkpw(clientSecret, clientEntity.getHash()))             throw new LoginException(\"Secret is incorrect\");     }      \/**\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0430\u0446\u0435\u0441\u0441 \u0438 \u0440\u0435\u0444\u0440\u0435\u0448 \u0442\u043e\u043a\u0435\u043d\u044b*\/     private AuthResponseDto generateNewAccessAndRefreshTokens(String clientId, String audience) {         String roles=userRepository.findByClientIdAndAudience(clientId, audience).get().getRoles();         String access=tokenService.generateAccessToken(clientId, audience, roles);         String refresh=tokenService.generateRefreshToken(clientId, audience);         this.refreshStorage.put(clientId+\"-\"+ audience, refresh);         return new AuthResponseDto(access, refresh);     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0441\u0447\u0451\u0442\u0435 \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u0430\u043a<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/209\/7d2\/3df\/2097d23df229a4cd291163e8e4cb8f31.png\" width=\"330\" height=\"621\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/209\/7d2\/3df\/2097d23df229a4cd291163e8e4cb8f31.png\"\/><\/figure>\n<details class=\"spoiler\">\n<summary>\u0422\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0441\u0435\u0440\u0432\u0438\u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u043d\u0430\u0447\u0435 \u0441\u0435\u0440\u0432\u0438\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0438<\/p>\n<p>\u041f\u043e\u043c\u043d\u0438\u0442\u0435 \u043c\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u043b\u0438 swagger? \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f.<br \/>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430 <a href=\"http:\/\/localhost:8079\/swagger-ui\/index.html\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:8079\/swagger-ui\/index.html<\/a><br \/>\u0412\u0438\u0434\u0438\u043c \u0432\u0441\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u0432\u0435\u0431&#8212;\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ac2\/e07\/3e3\/ac2e073e3031ebbce43e13a08c32ffd6.png\" alt=\"\" title=\"\" width=\"1336\" height=\"255\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ac2\/e07\/3e3\/ac2e073e3031ebbce43e13a08c32ffd6.png\"\/><\/figure>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0447\u0442\u043e \u043c\u044b \u0430\u0434\u043c\u0438\u043d\u044b \u0438 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/41a\/789\/e6e\/41a789e6e19bd058e9e0737047ee07a6.png\" width=\"1296\" height=\"825\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/41a\/789\/e6e\/41a789e6e19bd058e9e0737047ee07a6.png\"\/><\/figure>\n<p>\u041f\u043e\u043c\u043d\u0438\u043c \u0447\u0442\u043e \u043d\u0430\u0448\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u044b \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0431\u0434 h2 \u0438 \u043c\u044b \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u043b\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043d\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u043a\u043e\u043d\u0441\u043e\u043b\u044c.<br \/>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u0447\u0435\u0440\u0435\u0437 <a href=\"http:\/\/localhost:8079\/h2-console\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:8079\/h2-console<\/a><br \/>\u0418 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f01\/054\/176\/f0105417690c492b977703aa0a448a5e.png\" width=\"1068\" height=\"823\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f01\/054\/176\/f0105417690c492b977703aa0a448a5e.png\"\/><\/figure>\n<p>\u041c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0434\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043b\u043e\u0433\u0438\u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u0442\u043e\u043a\u0435\u043d\u044b \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0440\u0435\u0444\u0440\u0435\u0448\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0443\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0430\u0446\u0435\u0441\u0441-\u0442\u043e\u043a\u0435\u043d\u0430.<br \/>\u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0438\u0436\u0435, \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0433\u0435\u0439\u0442\u0432\u0435\u044f<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b<br \/><a href=\"https:\/\/tproger.ru\/articles\/pishem-java-veb-prilozhenie-na-sovremennom-steke-s-nulja-do-mikroservisnoj-arhitektury-chast-2\" rel=\"noopener noreferrer nofollow\">https:\/\/tproger.ru\/articles\/pishem-java-veb-prilozhenie-na-sovremennom-steke-s-nulja-do-mikroservisnoj-arhitektury-chast-2<\/a><br \/><a href=\"https:\/\/struchkov.dev\/blog\/ru\/jwt-implementation-in-spring\/\" rel=\"noopener noreferrer nofollow\">https:\/\/struchkov.dev\/blog\/ru\/jwt-implementation-in-spring\/<\/a><br \/><a href=\"https:\/\/habr.com\/ru\/articles\/784508\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/articles\/784508\/<\/a><\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0435\u0440\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0440\u0438\u043d\u0433-\u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438 (WebApplication)<\/summary>\n<div class=\"spoiler__content\">\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438 SpringSimple \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 Apps \u0433\u0434\u0435 \u0431\u0443\u0434\u0443\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f WebApplication<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/676\/d08\/fdb\/676d08fdb019726af1f40a2f88e1521e.png\" width=\"326\" height=\"555\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/676\/d08\/fdb\/676d08fdb019726af1f40a2f88e1521e.png\"\/><\/figure>\n<p>\u0412 \u0444\u0430\u0439\u043b \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 SpringSimple\\settings.gradle \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043d\u0430\u0448 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442: include &#8216;Apps:WebApplication&#8217;<\/p>\n<details class=\"spoiler\">\n<summary>build.gradle<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041a \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u043c \u0438\u0437 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (\u0438\u0437 \u0441\u0435\u043a\u0446\u0438\u0438 subprojects \u0444\u0430\u0439\u043b\u0430 SpringSimple\\build.gradle) \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0431\u0434 (\u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c hiberate) \u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u0435\u0431-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432<\/p>\n<pre><code class=\"java\">group = 'ru.app' version = '1.0-SNAPSHOT'  dependencies {     \/\/spring     implementation 'org.springframework.boot:spring-boot-starter-data-jpa'     implementation 'org.springframework.boot:spring-boot-starter-web'       \/\/db     runtimeOnly 'com.h2database:h2'     \/\/runtimeOnly 'org.postgresql:postgresql'     testImplementation 'com.h2database:h2:2.2.224' } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application.properties<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0424\u0430\u0439\u043b \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a, \u043a\u0440\u043e\u043c\u0435 \u0438\u043c\u0435\u043d\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u0440\u0442\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0438 \u0442\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442 \u043d\u0435\u0433\u043e<\/p>\n<pre><code class=\"java\">spring.application.name=WebApplication1 server.port=8080  #config spring.profiles.active=authSecret, swagger, hibernate, WebApplication1, actuator, ext, adminClient spring.cloud.config.fail-fast=true spring.cloud.config.uri=http:\/\/localhost:8888 spring.config.import=optional:configserver:http:\/\/localhost:8888 spring.cloud.config.import-check.enabled=true<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>WebApplication.java<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.app;  import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import ru.app.db.service.GenerateDataInDbService; import ru.app.utils.ApplicationContextProvider;  @SpringBootApplication public class WebApplication {      public static void main(String[] args) {       \/\/\u0437\u0430\u043f\u0443\u0441\u043a \u0441\u043f\u0440\u0438\u043d\u0433\u0430         SpringApplication.run(WebApplication.class, args);       \/\/\u043d\u0430\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0431\u0434 \u0442\u0430 \u043a\u0430\u043a \u043e\u043d\u0430, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c, \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u043b\u0435\u044c\u043d\u043e, \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f         ApplicationContextProvider.getBean(GenerateDataInDbService.class).generate();     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/summary>\n<div class=\"spoiler__content\">\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b<\/summary>\n<div class=\"spoiler__content\">\n<p>ObjectMapperWrapper \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432 json-\u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0438\u0445 \u043e\u0431\u0440\u0430\u0442\u043d\u043e.<br \/>\u0421\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u0430\u043f\u043f\u0435\u0440 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u043c\u0430\u043f\u0435\u0440\u0435<\/p>\n<pre><code class=\"java\">package ru.app.utils;  import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.SneakyThrows;  \/**\u0412\u0440\u0430\u043f\u043f\u0435\u0440 \u0434\u043b\u044f \u043c\u0430\u043f\u0435\u0440\u0430 \u0438\u0437 \u0434\u0436\u0441\u043e\u043d\u0430 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e*\/ public class ObjectMapperWrapper {      private static final ObjectMapper mapper;      static{        mapper =new ObjectMapper();        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);        mapper.registerModule(new JavaTimeModule());        mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);     }      \/**\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 json-\u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442*\/     @SneakyThrows     public static &lt;T&gt; T readValue(String content, Class&lt;T&gt; valueType){         return mapper.readValue(content, valueType);     }      \/**\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 json-\u0441\u0442\u0440\u043e\u043a\u0443*\/     @SneakyThrows     public static String writeValueAsString(Object value) {         return  mapper.writeValueAsString(value);     } } <\/code><\/pre>\n<p>\u041a\u0440\u0430\u0439\u043d\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0448\u0442\u0443\u043a\u0430 ApplicationContextProvider \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0440\u0438\u043d\u0433\u043e\u0432\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u0438\u043d\u043e\u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438, \u043f\u043e \u0438\u0445 \u0438\u043c\u0435\u043d\u0438 \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441\u0443 \u0438, \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0432 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445<\/p>\n<pre><code class=\"java\">package ru.app.utils;  import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component;   \/**\u0414\u0430\u0451\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u043f\u0440\u0438\u043d\u0433\u043e\u0432\u0441\u043a\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0432 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u0438\/\u0438\u043b\u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0441\u043f\u0440\u0438\u043d\u0433\u0430*\/ @Component public class ApplicationContextProvider implements ApplicationContextAware {      private static ApplicationContext CONTEXT;      @Override     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {         CONTEXT = applicationContext;     }      public static &lt;T&gt; T getBean(Class&lt;T&gt; beanClass) {         return CONTEXT.getBean(beanClass);     }      public static Object getBean(String beanName) {         return CONTEXT.getBean(beanName);     } } <\/code><\/pre>\n<pre><code class=\"java\">public class Utils {     \/**\u0412\u0435\u0440\u043d\u0451\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 \u043d\u0435 \u043d\u0443\u043b\u0435\u0432\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0437 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445*\/     public static &lt;T&gt; T coalesce(T... items) {         for (T i : items) if (i != null) return i;         return null;     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0411\u0414<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412\u0441\u0435\u0433\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0431\u0449\u0435\u0433\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0430 \u0434\u043b\u044f \u0432\u0430\u0448\u0438\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u044d\u0442\u043e \u0440\u0435\u0448\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c.<br \/>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0438\u043c\u0435\u044f \u043e\u0431\u0449\u0435\u0433\u043e \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043a\u0430 AbstractEntity \u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0431\u0434 EntityService \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 (\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430) \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0430\u0440\u0442\u0435\u0433\u0438\u044f\u043c\u0438 \u043c\u044f\u0433\u043a\u043e\u0433\u043e (\u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437 \u0431\u0434, \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f) \u0438 \u0436\u0451\u0441\u0442\u043a\u043e\u0433\u043e (\u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f) \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"java\">package ru.app.db.entity;  import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.experimental.FieldDefaults; import org.hibernate.annotations.*; import org.springframework.core.annotation.AnnotatedElementUtils; import ru.app.db.service.EntityService;  import java.io.Serializable; import java.lang.reflect.Field; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors;  \/**\u041e\u0431\u0449\u0438\u0439 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043f\u0440\u0435\u0434\u043e\u043a \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439*\/ @MappedSuperclass @Getter @Setter @NoArgsConstructor @FieldDefaults(level = AccessLevel.PUBLIC) @SQLRestriction(\"deleted = false\")\/\/\u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0445\u0438\u0431\u0435\u0440\u0439\u043d\u0435\u0439\u0442\u0443 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u043c\u0435\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f (\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \"\u043c\u044f\u0433\u043a\u043e\u0433\u043e\" \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f) public abstract class AbstractEntity implements Cloneable, Serializable {     @Id     @GeneratedValue(strategy = GenerationType.IDENTITY)     Long id;      @Column(columnDefinition = \"boolean DEFAULT false\")     @JsonIgnore     Boolean deleted = false;      @CreationTimestamp \/\/https:\/\/www.baeldung.com\/hibernate-creationtimestamp-updatetimestamp     LocalDateTime createdDt;     @UpdateTimestamp     LocalDateTime modifiedDt;      \/**\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c. \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0438\u043b\u0438 \u043a\u0430\u043a-\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u044f*\/     public void beforeSave(){}      \/**\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435\u043c. \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u0435\u0440\u0435\u0434 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435\u043c \u0438 \u043d\u0435 \u0434\u0430\u0442\u044c \u0443\u0434\u0430\u043b\u0438\u0442\u044c*\/     public void beforeDelete(){}      \/**\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c      * @param entity - \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438      * @return - \u0441\u0430\u043c\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c*\/     static public&lt;A extends AbstractEntity&gt; A save(A entity){         return EntityService.self.save(entity);     }      \/**\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u043f\u043e \u0435\u0451 \u0443\u0438\u0434-\u0443      * @param id - \u0443\u0438\u0434 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438      * @param entityClass - \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043a\u043e\u043c\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438      * @return - \u0441\u0430\u043c\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0438\u043b\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0435\u0441\u043b\u0438 \u0435\u0451 \u043d\u0435 \u0431\u044b\u043b\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043e*\/     static public&lt;A extends AbstractEntity&gt; A findById(Class&lt;A&gt; entityClass, Long id){         return EntityService.self.findById(entityClass, id);     }      \/** \u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c      * @param entity - \u0443\u0434\u0430\u043b\u044f\u0435\u043c\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c      **\/     static public &lt;A extends AbstractEntity&gt; void delete(A entity){         EntityService.self.delete(entity);     }      \/**\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443      * @param query- \u0437\u0430\u043f\u0440\u043e\u0441      * @param isNativeQuery - \u0438\u0441\u0442\u0438\u043d\u0430 \u0435\u0441\u043b\u0438 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u043a\u043b \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u043b\u043e\u0436\u044c \u0435\u0441\u043b\u0438 hql-\u0437\u0430\u043f\u0440\u043e\u0441      * @param entityClass - \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043a\u043e\u043c\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438      * @return - \u0441\u0430\u043c\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0438\u043b\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0435\u0441\u043b\u0438 \u0435\u0451 \u043d\u0435 \u0431\u044b\u043b\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043e      *      * \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432      * \"select distinct e from WorkerEntity e where element(e.contacts).contact like '\"+\"%@%\"+\"'\"      * *\/     static public&lt;A extends AbstractEntity&gt; List&lt;A&gt; findForQuery(String query, Boolean isNativeQuery, Class&lt;A&gt; entityClass){         List&lt;A&gt; list = isNativeQuery ? EntityService.self.getEm().createNativeQuery(query, entityClass).getResultList() : EntityService.self.getEm().createQuery(query, entityClass).getResultList();         return list.stream().map(e -&gt; {             e = EntityService.lazyInitializer(e);             return e;         }).collect(Collectors.toList());     }      @Override     public boolean equals(Object obj) {         if (this.getId()==null || ((AbstractEntity) obj).getId()==null) return false;         if (!this.getClass().equals(obj.getClass())) return  false;         return ((AbstractEntity) obj).getId().equals(this.getId());     } } <\/code><\/pre>\n<details class=\"spoiler\">\n<summary>EntityService<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.app.db.service;  import jakarta.annotation.PostConstruct; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.hibernate.Session; import org.hibernate.proxy.HibernateProxy; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.app.db.entity.AbstractEntity;  import java.util.List;  \/**\u0421\u0435\u0440\u0432\u0438\u0441 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0432 \u0414\u0411 *\/ @Service @Slf4j @RequiredArgsConstructor @Getter public class EntityService {     @PersistenceContext     private EntityManager em;      public static EntityService self;      \/**\u0418\u0441\u0442\u0438\u043d\u0430 - \u0436\u0451\u0441\u0442\u043a\u043e\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f, \u043b\u043e\u0436\u044c - \u043c\u044f\u0433\u043a\u043e\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435*\/     @Value(\"${app.delete-is-true:false}\")     private boolean deleteIsTrue;      @PostConstruct     public void postConstructor(){         self=this;     }      \/**      * \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u043f\u043e \u0435\u0451 \u0443\u0438\u0434-\u0443 (\u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438)      *      * @param id          - \u0443\u0438\u0434 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438      * @param entityClass - \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043a\u043e\u043c\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438      * @return - \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0438\u043b\u0438 null, \u0435\u0441\u043b\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442      *\/     public &lt;A extends AbstractEntity&gt; A getReferenceForId(Class&lt;A&gt; entityClass, Long id){         \/*Hibernate \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 SQL-\u0437\u0430\u043f\u0440\u043e\u0441, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 \u043c\u0435\u0442\u043e\u0434 getReference.         \u0415\u0441\u043b\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0439, Hibernate \u0438\u043d\u0441\u0442\u0430\u043d\u0446\u0438\u0440\u0443\u0435\u0442 \u043f\u0440\u043e\u043a\u0441\u0438-\u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430          \u042d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u043d\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044e \u0441 \u043b\u0435\u043d\u0438\u0432\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u043e\u0436\u0435 \u0434\u0430\u0435\u0442 \u0432\u0430\u043c \u043f\u0440\u043e\u043a\u0441\u0438-\u043e\u0431\u044a\u0435\u043a\u0442.         \u0412 \u043e\u0431\u043e\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0435\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u0435\u0440\u0432\u043e\u043c\u0443 \u0436\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0443, \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0449\u0435\u043c\u0443\u0441\u044f \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u043c \u043a\u043b\u044e\u0447\u0435\u043c, Hibernate \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b.         \u042d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 Hibernate \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u0415\u0441\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430, Hibernate \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435         * *\/         return em.getReference(entityClass, id);     }      \/**      * \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u043f\u043e \u0435\u0451 \u0443\u0438\u0434-\u0443      *      * @param id          - \u0443\u0438\u0434 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438      * @param entityClass - \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043a\u043e\u043c\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438      * @return - \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c      *\/     @SuppressWarnings(\"unchecked\")     @SneakyThrows     public &lt;A extends AbstractEntity&gt; A findById(Class&lt;A&gt; entityClass, Long id) {         try {             A e = (A) em.createQuery(\"from \" + entityClass.getSimpleName() + \" where id=\" + id.toString()).getSingleResult();             return e;         } catch (Exception ex) {             log.error(\"No find entity for id\"+id, ex);             return null;         }     }      \/**      * \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e      *      * @param hql           - \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438      * @param startPosition - \u0441 \u043a\u0430\u043a\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c      * @param maxResult     - \u043f\u043e \u043a\u0430\u043a\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c      * @param entityClass   - \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043a\u043e\u043c\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438      * @return - \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c      *\/     @SuppressWarnings(\"unchecked\")     @SneakyThrows     public &lt;A extends AbstractEntity&gt; List&lt;A&gt; findByAllFromConditionals(Class&lt;A&gt; entityClass, String hql, Integer startPosition, Integer maxResult) {         if (hql.toLowerCase().contains(\"insert\") || hql.toLowerCase().contains(\"update\"))             throw new RuntimeException(\"bad sql request: \"+hql);          if (startPosition == null) startPosition = 0;         if (maxResult == null) maxResult = Integer.MAX_VALUE;         try {             log.info(hql);             List&lt;A&gt; list = em.createQuery(\"select distinct e \"+hql, entityClass).setFirstResult(startPosition).setMaxResults(maxResult).getResultList();             return list;         } catch (Exception ex) {             log.error(\"Error select for: \" + hql, ex);             throw ex;         }     }      \/**      * \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0432 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u043c \u043d\u0430\u0431\u043e\u0440\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c      *      * @param hql - \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438      * @return - \u043e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439      *\/     @SuppressWarnings(\"unchecked\")     @SneakyThrows     public &lt;A extends AbstractEntity&gt; Integer findByAllFromConditionalsCount(String hql) {         if (hql.toLowerCase().contains(\"insert\") || hql.toLowerCase().contains(\"update\"))             throw new RuntimeException(\"bad sql request: \"+hql);          int i=hql.indexOf(\"order\");         if (i&gt;0)             hql=hql.substring(0, i);         try {             return Integer.parseInt(em.createQuery(\"select count(distinct e) \" + hql).getSingleResult().toString());         } catch (Exception ex) {             log.error(\"Error count select for: \" + hql, ex);             throw ex;         }     }       \/**      * \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0432 \u0431\u0434      *      * @param entity - \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c      * @return - \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c (\u043c\u0431 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0439-\u0434\u0438 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u043b\u044f)      *\/     @SneakyThrows     @Transactional     public &lt;S extends AbstractEntity&gt; S save(S entity) {         entity.beforeSave();         if (entity.getId() == null) em.persist(entity);         else entity=em.merge(entity);          return entity;     }      \/**\u0423\u0434\u0430\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u044c. \u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435, \u0438\u043b\u0438 \u043f\u0441\u0435\u0432\u0434\u043e-\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a*\/     @Transactional     public void delete(AbstractEntity entity) {         entity.beforeDelete();          \/\/em.remove(em.contains(entity) ? entity : em.merge(entity));\/\/delete entity          if (deleteIsTrue)             em.remove(em.contains(entity) ? entity : em.merge(entity));\/\/hard delete entity         else{\/\/soft delete             entity.setDeleted(true);             \/\/todo: \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e CascadeType             \/*\u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \"\u043c\u044f\u0433\u043a\u043e\u0433\u043e\" \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0430             @SQLDelete(sql = \"update Worker_Entity set deleted=true where id=?\") \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u0438\u043c\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443             @SoftDelete(columnName = \"deleted\") \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c lazy-\u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439*\/             save(entity);         }     }      \/**\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u0435\u0451 \u0442\u0435\u043a\u0441\u0442\u0432\u043e\u043c\u0443 \u0438\u043c\u0435\u043d\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u0432\u043e \u0432\u0441\u0435\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u0445      * @param entityClassName - \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438      * @return - \u043a\u043b\u0430\u0441\u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438*\/     public Class&lt;? extends AbstractEntity&gt; getEntityClassForName(String entityClassName){         var entityImpl =em.getMetamodel().getEntities().stream().filter(elem -&gt; elem.getName().equals(entityClassName)).findFirst().orElseThrow(()-&gt; new RuntimeException(\"no find entity class with class name is \"+entityClassName));         return (Class&lt;? extends AbstractEntity&gt;) entityImpl.getJavaType();     }      \/**      * \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043b\u0435\u043d\u0438\u0432\u0443\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443, \u0438\u043d\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0451 \u043f\u043e\u043b\u044f. \u041d\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0411\u0414 \u043d\u0435 \u0438\u0434\u0451\u0442      *      * @param ae - \u043f\u043e\u0442\u043e\u043c\u043e\u043a AbstractEntity, \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0430\u044f \u0447\u0435\u0440\u0435\u0437 \u043b\u0435\u043d\u0438\u0432\u0443\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443      * @return - \u0442\u0430 \u0436\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, \u043d\u043e \u0441 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438      *\/     @SuppressWarnings(\"unchecked\")     public static &lt;R extends AbstractEntity&gt; R lazyInitializer(R ae) {         if (ae != null)             if (ae.id == null)                 if (ae.getId() != null)                     return (R) ((HibernateProxy) ae).getHibernateLazyInitializer().getImplementation(); \/\/\u0435\u0441\u043b\u0438 \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u043f\u043e\u043b\u0435 \u043d\u0435 \u0431\u044b\u043b\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u043e, \u0442\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u0451\u043c \u0435\u0433\u043e \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e                 else return null;             else return ae;         return null;     }  } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430\u0448\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438: \u0440\u0430\u0431\u043e\u0442\u043d\u0438\u043a \u0438 \u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u044b.<br \/>\u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f \u043e\u043d\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442\u0441\u044f \u043e\u0442 AbstractEntity<\/p>\n<pre><code class=\"java\">\/**\u0421\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a*\/ @Entity @Getter @Setter @FieldDefaults(level = AccessLevel.PUBLIC) @Lazy @SQLRestriction(\"deleted = false\") @JsonInclude(JsonInclude.Include.NON_NULL) \/\/\u043f\u0440\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 json \u043d\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0443\u043b\u0435\u0432\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f public class WorkerEntity extends AbstractEntity {     \/**\u0418\u043c\u044f \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u0430*\/     @JsonIgnore     String lastName=\"\";     @JsonIgnore     String firstName=\"\";      public String getFullName(){         return lastName +\" \" +firstName;     }      \/**\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u044b \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u0430*\/     @OneToMany(mappedBy = \"worker\", fetch = FetchType.LAZY, cascade = CascadeType.ALL)     \/\/@JsonManagedReference     Set&lt;ContactEntity&gt; contacts=new HashSet&lt;&gt;();      \/**\u0417\u0430\u043c\u0435\u0442\u043a\u0438 \u043e \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u0435*\/     @ElementCollection     List&lt;String&gt; notes=new ArrayList&lt;&gt;(); }   \/**\u041a\u043e\u043d\u0442\u0430\u043a\u0442*\/ @Entity @Getter @Setter @FieldDefaults(level = AccessLevel.PUBLIC) @SQLRestriction(\"deleted = false\") @JsonInclude(JsonInclude.Include.NON_NULL) public class ContactEntity extends AbstractEntity {     \/**\u0442\u0438\u043f \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u0430*\/     @Enumerated(EnumType.STRING)     ContactTypeEnum type;      \/**\u0441\u0430\u043c \u043a\u043e\u043d\u0442\u0430\u043a\u0442*\/     String contact;      \/**\u043f\u043e\u043b\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0432\u044f\u0437\u0438*\/     @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)     \/\/@JsonBackReference  https:\/\/www.baeldung.com\/jackson-bidirectional-relationships-and-infinite-recursion     @JsonIgnore \/\/\u043d\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0432\u044f\u0437\u0438 \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u043d\u0430\u0447\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e \u043f\u0440\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438     WorkerEntity worker; }<\/code><\/pre>\n<p>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c\u0438:<\/p>\n<pre><code class=\"java\">    \/**\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0431\u0434: \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u043e\u0432 \u0438 \u0438\u0445 \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u044b*\/     @Transactional     public void generate(){         Random randomizer = new Random();         for(int i=0; i &lt; 10; i++){             WorkerEntity worker =  new WorkerEntity();             worker.setLastName(List.of(\"\u0418\u0432\u0430\u043d\u043e\u0432\",\"\u0421\u0438\u0434\u043e\u0440\u043e\u0432\",\"\u041a\u043e\u0437\u043b\u043e\u0432\",\"\u041f\u0435\u0442\u0440\u043e\u0432\",\"\u0411\u0430\u0433\u0440\u043e\u0432\").get(randomizer.nextInt(5)));             worker.setFirstName(List.of(\"\u0418\u0432\u0430\u043d\",\"\u0421\u0438\u0434\u043e\u0440\",\"\u0418\u043b\u044c\u044f\",\"\u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\",\"\u0414\u0430\u043d\u0438\u043b\u0430\").get(randomizer.nextInt(5)));              for(int j=0; j &lt; randomizer.nextInt(4); j++){                 ContactEntity contact = new ContactEntity();                 contact.setType(getRandomValueFromEnum(ContactTypeEnum.values()));                 contact.setContact(\"123456\");                 contact.setWorker(worker);                 contact=AbstractEntity.save(contact);                 worker.getContacts().add(contact);             }              for(int j=0; j &lt; randomizer.nextInt(4); j++)                 worker.getNotes().add(List.of(\"\u0425\u043e\u0440\u043e\u0448\u0438\u0439 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\",\"\u041f\u043b\u043e\u0445\u043e\u0439 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\",\"\u0412\u0435\u0447\u043d\u043e \u043e\u043f\u0430\u0437\u0434\u044b\u0432\u0430\u0435\u0442\",\"\u041f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\",\"\u041a\u043e\u043b\u043b\u0435\u0433 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0431\u0440\u0430\u0442\u044c\u044f\u043c\u0438 \u0438 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 '\u0432 \u0447\u0451\u043c \u0441\u0438\u043b\u0430?'\").get(randomizer.nextInt(4)));              worker = AbstractEntity.save(worker);         }     }  \/\/\u0432\u044b\u0431\u043e\u0440\u043a\u0430 \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e (\u0438\u043b\u0438 \u0431\u0435\u0437 \u0443\u0441\u043b\u043e\u0432\u0438\u044f): AbstractEntity.findForQuery(\"select we from WorkerEntity we\",false, WorkerEntity.class) \/\/\u043f\u043e\u0438\u0441\u043a \u043f\u043e \u0443\u0438\u0434-\u0443 AbstractEntity.findById(WorkerEntity.class, workerId) \/\/\u043f\u043e\u0438\u0441\u043a \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 AbstractEntity.delete(AbstractEntity.findById(WorkerEntity.class, workerId));       \/**      * \u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u0437 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u0438\u044f      *\/     private static &lt;V extends Enum&lt;V&gt;&gt; V getRandomValueFromEnum(V[] enumArray) {         return Arrays.stream(enumArray).toList().get((new Random()).nextInt(enumArray.length));     }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043d\u044b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0438<\/summary>\n<div class=\"spoiler__content\">\n<details class=\"spoiler\">\n<summary>AppProperties<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0425\u0440\u0430\u043d\u0438\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435<\/p>\n<pre><code class=\"java\">\/**\u041a\u043b\u0430\u0441\u0441\u0441 \u0441\u0432\u043e\u0439\u0441\u0442\u0432*\/ @Component @Getter @FieldDefaults(level = AccessLevel.PRIVATE) public class AppProperties {     \/**\u0423\u0418\u0414-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f*\/     @Value(\"${spring.application.name:none}\")     String appName;      \/**\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043b\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f*\/     @Value(\"${auth.enabled:true}\")     private Boolean enabled;      public static AppProperties self;      @PostConstruct     public void postConstruct(){         self=this;     }  }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>SwaggerConfig &#8212; \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0432\u0430\u0433\u0435\u0440\u0430 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.app.config;  import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.info.Contact; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.security.SecurityScheme;  \/\/https:\/\/struchkov.dev\/blog\/ru\/api-swagger\/  \/\/\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0432\u0430\u0433\u0435\u0440\u0440\u0430 @OpenAPIDefinition(         info = @Info(                 title = \"\u0422\u0435\u0441\u0442\u043e\u0432\u043e\u0435 Api\",                 description = \"\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0410\u041f\u0418\",                 version = \"1.0.0\",                 contact = @Contact(                         name = \"\u0418\u0432\u0430\u043d \u0418\u0432\u0430\u043d\u043e\u0432\",                         email = \"ivan@ivanov.ruv\",                         url = \"https:\/\/ivan.ivanov.ru\"                 )         ) ) \/\/\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u0441\u043f \u0441\u0432\u0430\u0433\u0433\u0435\u0440 @SecurityScheme(         name = \"JWT\",         type = SecuritySchemeType.HTTP,         bearerFormat = \"JWT\",         scheme = \"bearer\" ) \/*@SecurityScheme(   \/\/for spring security         name = \"jsessionid\",         type = SecuritySchemeType.APIKEY,         in = SecuritySchemeIn.COOKIE,         paramName = \"JSESSIONID\" )*\/ public class SwaggerConfig { } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>WebMvcConfig<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u043b\u0430 CORS-\u0437\u0430\u043f\u0440\u043e\u0441\u044b (\u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 \u0433\u0435\u0439\u0442\u0432\u0435\u0439)<br \/>\u0422\u0430\u043a\u0436\u0435 \u0438\u043d\u043e\u0433\u0434\u0430 \u0431\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043a rest-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<pre><code class=\"java\">package ru.app.config;  import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.util.ContentCachingResponseWrapper;  import java.util.Enumeration;  @Configuration public class WebMvcConfig implements WebMvcConfigurer {      \/**\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c CORS \u0434\u043b\u044f \u0441\u0432\u0430\u0433\u0433\u0435\u0440\u0430*\/     @Override     public void addCorsMappings(CorsRegistry registry) {         registry.addMapping(\"\/**\");         \/\/registry.addMapping(\"\/api-docs\"); \/\/\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0441\u0432\u0430\u0433\u0433\u0435\u0440\u0430     }      \/**\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0432\u043e\u0439 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043a*\/     @Override     public void addInterceptors(InterceptorRegistry registry) {         registry.addInterceptor(new LoggerInterceptor());     } }   \/\/https:\/\/www.baeldung.com\/spring-mvc-handlerinterceptor \/**\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043a \u0434\u043b\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0435\u0433\u043e*\/ @Slf4j class LoggerInterceptor implements HandlerInterceptor {     @Override     \/**\u041a\u0430\u043a \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043a \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 preHandle() \u043f\u0435\u0440\u0435\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.      \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 true, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u0430\u043b\u044c\u0448\u0435, \u043a \u043c\u0435\u0442\u043e\u0434\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u044c Spring \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435, \u0432\u0435\u0440\u043d\u0443\u0432 false.      \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u0443\u043a \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043e \u0442\u043e\u043c, \u043e\u0442\u043a\u0443\u0434\u0430 \u043f\u0440\u0438\u0448\u0451\u043b \u0437\u0430\u043f\u0440\u043e\u0441.*\/     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {         log.info(\"[preHandle][\" + request + \"]\" + \"[\" + request.getMethod() + \"]\" + request.getRequestURI() + getParameters(request));         return true;     }      @Override     \/**\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u043f\u043e\u0441\u043b\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f*\/     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {         if (ex != null){             ex.printStackTrace();         }          log.info(\"[afterCompletion][\" + request + \"][exception: \" + ex + \"] =&gt; \"+response);     }       private String getParameters(HttpServletRequest request) {         StringBuffer posted = new StringBuffer();         Enumeration&lt;?&gt; e = request.getParameterNames();         if (e != null) {             posted.append(\"?\");         }         while (e.hasMoreElements()) {             if (posted.length() &gt; 1) {                 posted.append(\"&amp;\");             }             String curr = (String) e.nextElement();             posted.append(curr + \"=\");             if (curr.contains(\"password\")                     || curr.contains(\"pass\")                     || curr.contains(\"pwd\")) {                 posted.append(\"*****\");             } else {                 posted.append(request.getParameter(curr));             }         }         String ip = request.getHeader(\"X-FORWARDED-FOR\");         String ipAddr = (ip == null) ? getRemoteAddr(request) : ip;         if (ipAddr!=null &amp;&amp; !ipAddr.equals(\"\")) {             posted.append(\"&amp;_psip=\" + ipAddr);         }         return posted.toString();     }      private String getRemoteAddr(HttpServletRequest request) {         String ipFromHeader = request.getHeader(\"X-FORWARDED-FOR\");         if (ipFromHeader != null &amp;&amp; ipFromHeader.length() &gt; 0) {             log.debug(\"ip from proxy - X-FORWARDED-FOR : \" + ipFromHeader);             return ipFromHeader;         }         return request.getRemoteAddr();     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043e\u043f\u0438\u0448\u0435\u043c \u0444\u0438\u043b\u044c\u0442\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u0440\u0435\u0448\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u043b \u043d\u0435\u0442<\/p>\n<details class=\"spoiler\">\n<summary>AuthorizationFilter<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.app.api.auth;  import com.auth0.jwt.interfaces.DecodedJWT; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.filter.OncePerRequestFilter;  import java.io.IOException; import java.util.Arrays; import java.util.List;  \/**\u0424\u0438\u043b\u044c\u0442\u0440 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0438\u0439 \u0430\u0446\u0435\u0441\u0441-\u0442\u043e\u043a\u0435\u043d \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0434\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443 auth-service \u0435\u0441\u043b\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f*\/ @Component @RequiredArgsConstructor public class AuthorizationFilter extends OncePerRequestFilter {      private final TokenService tokenService;      @Value(\"${auth.enabled}\")     private boolean enabled;      @Override     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {         if (!enabled \/\/\u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0431\u0435\u0437 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445                 || request.getMethod().equals(HttpMethod.OPTIONS.name())                 || request.getRequestURI().contains(\"\/public\/\")                 || request.getRequestURI().contains(\"\/h2-console\")                 || request.getRequestURI().contains(\"\/actuator\")                 || request.getRequestURI().contains(\"\/swagger-ui\")                 || request.getRequestURI().contains(\"\/api-docs\")         ) {             filterChain.doFilter(request, response);             return;         }        \/\/\u0437\u0434\u0435\u0441\u044c, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043c\u044b \u0442\u0440\u0435\u0431\u0443\u0435\u043c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e. \u0415\u0441\u043b\u0438 \u0435\u0451 \u043d\u0435\u0442 - \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c - \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u0438 \u0435\u0441\u043b\u0438 \u043e\u043d \u0432\u0430\u043b\u0438\u0434\u0435\u043d, \u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0440\u043e\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 RequestContextHolder.getRequestAttributes().setAttribute         String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);          if (authHeader == null || authHeader.isBlank())             response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);         else {             DecodedJWT decodedJWT = checkAuthorization(authHeader);             if (decodedJWT==null)                 response.setStatus(HttpServletResponse.SC_FORBIDDEN);             else {                 \/\/\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0448\u043b\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e                 \/\/\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430                 \/\/\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043a\u0430\u043a RequestContextHolder.getRequestAttributes().getAttribute(\"roles\", 0);                 RequestContextHolder.getRequestAttributes().setAttribute(\"clientId\", decodedJWT.getSubject(), 0);                 RequestContextHolder.getRequestAttributes().setAttribute(\"roles\", Arrays.stream(decodedJWT.getClaim(\"roles\").asString().split(\",\")).toList().stream().map(String::trim).toList(), 0);                  filterChain.doFilter(request, response);             }         }     }      private DecodedJWT checkAuthorization(String auth) {         if (!auth.startsWith(\"Bearer \"))             return null;          String token = auth.substring(7);         return tokenService.checkToken(token);     } } <\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u043c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0445 \u0430\u043f\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0442\u0438\u043f\u0430 OPTIONS<\/p>\n<p>\u0414\u043b\u044f \u0432\u0441\u0435\u0445 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u0430. \u0415\u0441\u043b\u0438 \u043e\u043d \u0432\u0430\u043b\u0438\u0434\u0435\u043d \u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0440\u043e\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 RequestContextHolder<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>AuthorizationService &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u043e\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043a \u0430\u043f\u0438 \u0438\/\u0438\u043b\u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\"> @Slf4j public class AuthorizationService {     \/**      * \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442, \u0447\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u043c\u0435\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0440\u043e\u043b\u044c \u0438\u043b\u0438 \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435      * \u0415\u0441\u043b\u0438 \u043a\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f \u043e\u0442 \u043b\u0438\u0446\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0442\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442      *\/     public static void checkRole(String roleName) {         if (!AppProperties.self.getEnabled()){             log.info(\"authorization disabled\");             return;         }          try {             String clientId = (String) RequestContextHolder.getRequestAttributes().getAttribute(\"clientId\", 0);             List&lt;String&gt; roles = (List&lt;String&gt;) RequestContextHolder.getRequestAttributes().getAttribute(\"roles\", 0);             Boolean result = roles.contains(roleName);             log.info(\"clientId={} with roles={} check roleName={} result is {}\", clientId, roles, roleName, result);             if (!result)                 throw new RuntimeException(\"clientId=\" + clientId + \" no have role=\" + roleName);          } catch (NullPointerException e) {             log.info(\"clientId={} with roles={} check roleName={} result is {}\", \"system\", \"[*]\", roleName, true);         }     }       \/**      * \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442, \u0447\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u043c\u0435\u0435\u0442 \u0432\u0441\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0440\u043e\u043b\u0438 \u0438\u043b\u0438 \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435      * \u0415\u0441\u043b\u0438 \u043a\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f \u043e\u0442 \u043b\u0438\u0446\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0442\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442      *\/     public static void checkRolesAnd(List&lt;String&gt; roles) {         roles.forEach(roleName -&gt; checkRole(roleName));     }      \/**      * \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442, \u0447\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u043c\u0435\u0435\u0442 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u0443 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u044e \u0440\u043e\u043b\u044c \u0438\u043b\u0438 \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435      * \u0415\u0441\u043b\u0438 \u043a\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f \u043e\u0442 \u043b\u0438\u0446\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0442\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442      *\/     public static void checkRolesOr(List&lt;String&gt; roles) {         boolean result=false;         for (String roleName : roles)             try {                 checkRole(roleName);                 result=true;                 break;             } catch (RuntimeException re) {}         if (!result)             throw new RuntimeException(\"No find role in client for roles=\" + roles);      } }<\/code><\/pre>\n<p>\u0421\u043e\u043e\u0442\u0432\u0442\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0430\u043f\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0441 \u0440\u043e\u043b\u044c\u044e ROLE_WEB \u043c\u044b \u043f\u0438\u0448\u0435\u043c<\/p>\n<pre><code class=\"java\">    @GetMapping(\"\/hello\")     public AnswerDto hello(@RequestParam(required = false) String name) {         AuthorizationService.checkRole(\"ROLE_WEB\");         return new AnswerDto().setData(\"Hello, \" + name);     }<\/code><\/pre>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445.<br \/>\u041c\u043e\u0436\u043d\u043e \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0440\u043e\u043b\u044f\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f checkRolesAnd \u0438\u043b\u0438 checkRolesOr<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u043e\u043a\u0435\u043d\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">\/**\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0442\u043e\u043a\u0435\u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u0443 AuthService-\u0430*\/ public interface TokenService {     \/** \u0412\u0435\u0440\u043d\u0451\u0442 \u0440\u0430\u0441\u043a\u043e\u0434\u0438\u0440\u0432\u043e\u0430\u043d\u043d\u044b\u0439 jwt-\u0442\u043e\u043a\u0435\u043d \u0435\u0441\u043b\u0438 \u043e\u043d \u0432\u0430\u043b\u0438\u0434\u0435\u043d \u0438\u043b\u0438 null \u0435\u0441\u043b\u0438 \u043d\u0435 \u0432\u0430\u043b\u0438\u0434\u0435\u043d*\/     DecodedJWT checkToken(String token); }   @Service @Slf4j @RequiredArgsConstructor public class DefaultTokenService implements TokenService {     @Value(\"${auth.jwt.secret.access}\")     private String secretKey;     @Value(\"${spring.application.name}\")     private String appName;      @Override     public DecodedJWT checkToken(String token) {         Algorithm algorithm = Algorithm.HMAC256(secretKey);         JWTVerifier verifier = JWT.require(algorithm).build();          try {             DecodedJWT decodedJWT = verifier.verify(token);             if (!decodedJWT.getIssuer().equals(\"auth-service\")) {                 log.error(\"Issuer is incorrect\");                 return null;             }              if (!decodedJWT.getAudience().contains(appName)) {                 log.error(\"Audience is incorrect\");                 return null;             }              return decodedJWT;         } catch (JWTVerificationException e) {             log.error(\"Token is invalid: \" + e.getMessage());             return null;         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<p>\u0420\u0435\u0430\u043b\u0437\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432 \u043e\u043f\u0443\u0449\u0435\u043d\u0430. \u041c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0435\u0451 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435.<br \/>\u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e @SecurityRequirement(name = &#171;JWT&#187;) \u0438\u043d\u0430\u0447\u0435 \u0441\u0432\u0430\u0433\u0433\u0435\u0440 \u043d\u0435 \u043f\u043e\u0439\u043c\u0451\u0442 \u0447\u0442\u043e \u044d\u0442\u043e \u0437\u0430\u0449\u0438\u0449\u0451\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a \u043d\u0438\u043c \u0430\u0446\u0435\u0441\u0441-\u0442\u043e\u043a\u0435\u043d. \u0412\u043f\u0440\u043e\u0447\u0435\u043c \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0438\u0445 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438\u0437 postman-\u0430<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445 \u043d\u0430 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043a \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439. \u0418\u043d\u043e\u0433\u0434\u0430 \u0431\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0430\u043f\u0438 \u0435\u0434\u0438\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c<\/p>\n<pre><code class=\"java\">\/**\u041f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439*\/ @ControllerAdvice @Slf4j public class DefaultAdvice {     @ExceptionHandler(Exception.class)     public ResponseEntity&lt;AnswerDto&gt; handleException(Exception e) {         log.error(\"\u041f\u0435\u0440\u0435\u0445\u0432\u0430\u0447\u0435\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430: \",e);          AnswerDto response = new AnswerDto();         response.setErrorText(e.getClass().getName()+\": \"+e.getLocalizedMessage()+(e.getCause()!=null ? \" (\"+e.getCause().toString()+\")\" : \"\"));         response.setErrorType(e.getClass().getSimpleName());          return new ResponseEntity&lt;&gt;(response, HttpStatus.INTERNAL_SERVER_ERROR);     } }<\/code><\/pre>\n<p>\u0410 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430 \u043b\u0438\u0441\u0442\u0435\u043d\u0435\u0440 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u043e\u0442\u043b\u043e\u0432\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 \/actuator\/refresh \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0441\u043f\u0440\u0438\u043d\u0433-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u0435\u0451 \u0437\u0430\u043d\u043e\u0432\u043e \u043e\u0442 \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/p>\n<pre><code class=\"java\">import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Service;  \/\/https:\/\/www.baeldung.com\/spring-reloading-properties \/\/https:\/\/habr.com\/ru\/companies\/otus\/articles\/590761\/ \/**\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u0430\u043a \u043e\u0442\u043b\u043e\u0432\u0438\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435  \/actuator\/refresh*\/ @Service @RefreshScope @Slf4j public class MyRefreshListener implements ApplicationListener&lt;EnvironmentChangeEvent&gt; {     @Value(\"${myValue:none}\")     private String myValue;      @Override     public void onApplicationEvent(EnvironmentChangeEvent event) {         if(event.getKeys().contains(\"myValue\")) {             log.info(\"REFRESH! myValue={}\",myValue);         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u0430\u043f\u0438 \u0431\u0435\u0437 \u0442\u043e\u043a\u0435\u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443 &#171;\u043d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d&#187;<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/be1\/acc\/499\/be1acc499e69b53cad584ab0313b6d1a.png\" width=\"1258\" height=\"678\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/be1\/acc\/499\/be1acc499e69b53cad584ab0313b6d1a.png\"\/><\/figure>\n<p>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u043c \u0442\u043e\u043a\u0435\u043d \u0432 \u0441\u0432\u0430\u0433\u0433\u0435\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e0c\/9ad\/2f3\/e0c9ad2f36eb788960130937da675b91.png\" width=\"1656\" height=\"873\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e0c\/9ad\/2f3\/e0c9ad2f36eb788960130937da675b91.png\"\/><\/figure>\n<p>\u0412\u0438\u0434\u0438\u043c \u0447\u0442\u043e \u0432\u0441\u0435 \u0430\u043f\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0445\u0440\u043e\u043c\u0435 \u0445\u044d\u043b\u043b\u043e\u0443-\u0430\u043f\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0443 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0440\u043e\u043b\u044c ROLE-WEB.<br \/>\u0415\u0441\u043b\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0434 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c client1 \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044d\u0442\u0430 \u0440\u043e\u043b\u044c \u0435\u0441\u0442\u044c, \u0442\u043e \u0445\u044d\u043b\u043b\u043e\u0443-\u0430\u043f\u0438 \u0442\u0430\u043a\u0436\u0435 \u0441\u0442\u0430\u043d\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0412\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432(WebSecurityApplication). \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0441\u043f\u0440\u0438\u043d\u0433-\u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043d\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0430\u043c\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0440\u043e\u043b\u0435\u0432\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043b\u043e\u0436\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0430 \u0441\u043f\u0440\u0438\u043d\u0433-\u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438.<\/p>\n<p>\u0421\u0440\u0430\u0437\u0443 \u0445\u043e\u0447\u0443 \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441: \u0437\u0430\u0447\u0435\u043c \u0433\u043e\u0440\u043e\u0434\u0438\u0442\u044c \u043e\u0433\u043e\u0440\u043e\u0434, \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438, \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0440\u0438\u043d\u0433-\u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438?<br \/>1. \u0421\u043f\u0440\u0438\u0433-\u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c. \u041f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0432\u044b\u0445\u043e\u0434\u044f\u0442 \u043d\u043e\u0432\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438, \u0441\u0442\u0430\u0440\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u043d\u043e\u0432\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0421 \u043c\u043e\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u044d\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0435\u0449\u0451 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u044b\u0440\u043e\u0432\u0430\u0442.<br \/>2. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043f\u0440\u0438\u0433-\u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438 \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f. \u0418\u043d\u043e\u0433\u0434\u0430 \u044d\u0442\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0438\u0434\u0443\u0442 \u0432 \u0440\u0430\u0437\u0440\u0435\u0437 \u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439.<br \/>3. \u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u044f \u0445\u043e\u0447\u0443 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e &#171;\u043c\u0438\u043a\u0440\u043e&#187;-\u0441\u0435\u0440\u0432\u0438\u0441, \u0442\u043e \u0435\u0441\u0442\u044c \u0432\u043e\u043e\u0431\u0449\u0435 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0440\u0438\u043d\u0433\u0430?<br \/>\u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044f \u0441\u0447\u0438\u0442\u0430\u044e, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u043d\u0430\u0434\u043e \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u043e\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442, \u0430 \u043a\u0430\u043a \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0443\u043c\u0435\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 (\u0441\u0435\u0440\u0434\u0446\u0435 \u0442\u043e\u0433\u043e \u0436\u0435 \u0441\u043f\u0440\u0438\u043d\u0433\u0430 \u0441 \u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0438 \u0444\u0430\u0431\u0440\u0438\u043a\u043e\u0439 \u0431\u0438\u043d\u043e\u0432 \u0432\u043f\u043e\u043b\u043d\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443 \u0437\u0430 \u043f\u0430\u0440\u0443 \u043d\u0435\u0434\u0435\u043b\u044c).<br \/>\u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043f\u0440\u0438\u043d\u0433-\u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u043d\u043e \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043e\u043c\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0418\u0442\u0430\u043a. \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0432 \u0443\u0434\u0430\u0447\u0438 \u0443 <a href=\"https:\/\/habr.com\/ru\/companies\/gaz-is\/articles\/727324\/\" rel=\"noopener noreferrer nofollow\">\u0415\u0440\u0448\u043e\u0432\u0430 <\/a>\u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c \u0432 build.gradle<\/p>\n<details class=\"spoiler\">\n<summary>application.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">spring.application.name=WebSecurityApplication1 server.port=8081  #config spring.profiles.active=authSecret, swagger, WebSecurityApplication, actuator, adminClient spring.cloud.config.fail-fast=true spring.cloud.config.uri=http:\/\/localhost:8888 spring.config.import=optional:configserver:http:\/\/localhost:8888 spring.cloud.config.import-check.enabled=true<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0441\u043f\u0440\u0438\u043d\u0433-\u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438<\/p>\n<pre><code class=\"java\"> @Configuration @EnableWebSecurity @EnableMethodSecurity(securedEnabled = true)  \/\/\u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0438\u0441\u043f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e Secured \u043d\u0430 \u043c\u0435\u0442\u043e\u0434\u0430\u0445, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0441\u043c https:\/\/www.baeldung.com\/spring-security-method-security @RequiredArgsConstructor public class SecurityConfiguration {     private final AuthorizationFilter authorizationFilter;      @Bean     public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {         http.csrf(AbstractHttpConfigurer::disable)                 \/\/ \u0421\u0432\u043e\u0435\u0433\u043e \u0440\u043e\u0434\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 CORS (\u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441\u043e \u0432\u0441\u0435\u0445 \u0434\u043e\u043c\u0435\u043d\u043e\u0432)                 .cors(cors -&gt; cors.configurationSource(request -&gt; {                     var corsConfiguration = new CorsConfiguration();                     corsConfiguration.setAllowedOriginPatterns(List.of(\"*\"));                     corsConfiguration.setAllowedMethods(List.of(\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\"));                     corsConfiguration.setAllowedHeaders(List.of(\"*\"));                     corsConfiguration.setAllowCredentials(true);                     return corsConfiguration;                 }))                 \/\/ \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u043c \u0442\u043e\u0447\u043a\u0430\u043c                 .authorizeHttpRequests(request -&gt; request                         \/\/ \u041c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043f\u0443\u0442\u044c, * - 1 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438, ** - \u043b\u044e\u0431\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438                         \/*permitAll - \u042d\u043d\u0434\u043f\u043e\u0438\u043d\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432\u0441\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c, \u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0438 \u043d\u0435\u0442                           authenticated - \u0422\u043e\u043b\u044c\u043a\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438                           hasRole - \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0440\u043e\u043b\u044c, \u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0431\u044b\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c                           hasAnyRole - \u0414\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u043d\u0443 \u0438\u0437 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u0440\u043e\u043b\u0435\u0439 (\u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u043a\u043e\u0434\u0435)*\/                         .requestMatchers(\"\/actuator\/**\").permitAll()                         .requestMatchers(\"\/swagger-ui\/**\", \"\/swagger-resources\/*\", \"\/api-docs\/**\").permitAll()                         .requestMatchers(\"\/app\/v1\/**\").hasRole(\"WEB\")                         .anyRequest().authenticated())                 .sessionManagement(manager -&gt; manager.sessionCreationPolicy(STATELESS))                 \/\/.authenticationProvider(authenticationProvider())                 .addFilterBefore(authorizationFilter, UsernamePasswordAuthenticationFilter.class);         return http.build();     } }<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u043d\u0430\u0448 \u0444\u0438\u043b\u044c\u0442\u0440 AuthorizationFilter \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c<\/p>\n<pre><code class=\"java\"> \/**\u0424\u0438\u043b\u044c\u0442\u0440 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0438\u0439 \u0430\u0446\u0435\u0441\u0441-\u0442\u043e\u043a\u0435\u043d \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0434\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443 auth-service \u0435\u0441\u043b\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f*\/ @Component @RequiredArgsConstructor public class AuthorizationFilter extends OncePerRequestFilter {      private final TokenService tokenService;      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {        \/* \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d\u043d\u044b\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c \u0440\u0430\u0437\u0435\u0440\u0435\u0448\u0451\u043d \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438.        \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u0442\u0440\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u043c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438         if (                    request.getRequestURI().contains(\"\/public\/\")                 || request.getRequestURI().contains(\"\/actuator\")                 || request.getRequestURI().contains(\"\/swagger-ui\")                 || request.getRequestURI().contains(\"\/api-docs\")         ) {             filterChain.doFilter(request, response);             return;         }*\/          String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);         if (authHeader==null || authHeader.isEmpty() || !authHeader.startsWith(\"Bearer \")) {             filterChain.doFilter(request, response);             return;         }          if (authHeader == null || authHeader.isBlank())             response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);         else {             DecodedJWT decodedJWT = checkAuthorization(authHeader);             if (decodedJWT==null)                 response.setStatus(HttpServletResponse.SC_FORBIDDEN);             else {                 \/\/\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0448\u043b\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e                 \/\/\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043f\u0440\u0438\u0433\u043e\u0432\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438                 \/\/\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043a\u0430\u043a SecurityContextHolder.getContext().getAuthentication()                 \/\/\u0418\u043c\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a\u0430\u043a SecurityContextHolder.getContext().getAuthentication().getName()                 List&lt;SimpleGrantedAuthority&gt; roles = Arrays.stream(decodedJWT.getClaim(\"roles\").asString().split(\",\")).toList().stream().map(String::trim).map(SimpleGrantedAuthority::new).toList();                  SecurityContext context = SecurityContextHolder.createEmptyContext();                 UsernamePasswordAuthenticationToken authToken =new UsernamePasswordAuthenticationToken(decodedJWT.getSubject(), null, roles);                 authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));                 context.setAuthentication(authToken);                 SecurityContextHolder.setContext(context);                  \/\/\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432                 filterChain.doFilter(request, response);             }         }     }      private DecodedJWT checkAuthorization(String auth) {         if (!auth.startsWith(\"Bearer \"))             return null;          String token = auth.substring(7);         return tokenService.checkToken(token);     } }<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c \u0447\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435 \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0443\u0448\u043b\u0430 \u0432 SecurityConfiguration, \u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u0435\u0430\u043d\u0441\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0435\u0433\u043e \u0440\u043e\u043b\u044f\u0445 \u043c\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432 SecurityContext<\/p>\n<p>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c, \u0438\u043c\u0435\u044f \u0441\u043f\u0440\u0438\u043d\u0433\u043e\u0432\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u043e\u043b\u0435\u0439 \u0441\u043f\u0440\u0438\u043d\u0433\u043e\u0432\u0441\u043a\u0438\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <a class=\"mention\" href=\"\/users\/secured(%7B&quot;role_hello&quot;%7D)\">@Secured({&#171;ROLE_HELLO&#187;})<\/a>\u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0438 <a class=\"mention\" href=\"\/users\/preauthorize(&quot;hasrole('admin')&quot;)\">@PreAuthorize(&#171;hasRole(&#8216;ADMIN&#8217;)&#187;)<\/a>\u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0430\u043f\u0438<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 (WebGenerateApplication) \u0431\u0435\u0437 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u043f\u0440\u0438\u043c\u0435\u0440 \u0430\u0432\u0442\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 &#171;api first&#187;<\/summary>\n<div class=\"spoiler__content\">\n<details class=\"spoiler\">\n<summary>build.gradle<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043a\u0430\u043a \u0440\u0430\u0437 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0433\u0435\u043d\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 &#8216;org.openapi.generator&#8217;<br \/>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u043d\u0435\u0433\u043e \u0441\u043c<br \/><a href=\"https:\/\/habr.com\/ru\/companies\/spring_aio\/articles\/833096\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/companies\/spring_aio\/articles\/833096\/<\/a> <br \/><a href=\"https:\/\/openvalue.blog\/posts\/2023\/11\/26\/communicating_our_apis_part2\/\" rel=\"noopener noreferrer nofollow\">https:\/\/openvalue.blog\/posts\/2023\/11\/26\/communicating_our_apis_part2\/<\/a> <br \/><a href=\"https:\/\/openapi-generator.tech\/docs\/generators\/#server-generators\" rel=\"noopener noreferrer nofollow\">https:\/\/openapi-generator.tech\/docs\/generators\/#server-generators<\/a><\/p>\n<p>\u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 compileJava \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u043b\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0430\u043f\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u043c\u0443 \u0432 petclinic-spec.yml.<br \/>\u041c\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0431\u044d\u043a\u0430 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 java \u0438 \u043f\u043e\u0434 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0441\u043f\u0440\u0438\u043d\u0433\u0430, \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0434 \u0430\u043d\u0433\u0443\u043b\u044f\u0440 \u0434\u043b\u044f \u0444\u0440\u043e\u043d\u0442\u0430.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e sourceSet \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043a\u0430\u043a \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432<\/p>\n<pre><code class=\"java\">group = 'ru.app.gen' version = '0.0.1-SNAPSHOT'  apply plugin: 'org.openapi.generator'  java { toolchain { languageVersion = JavaLanguageVersion.of(21) } }  dependencies { implementation 'org.springframework.boot:spring-boot-starter-web'  \/\/swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'  implementation 'jakarta.validation:jakarta.validation-api:3.0.2' implementation 'javax.servlet:javax.servlet-api:3.0.1' implementation 'org.openapitools:jackson-databind-nullable:0.2.6' }   tasks.named('compileJava') { dependsOn(tasks.openApiGenerate) }   \/\/restclient \/* openApiGenerate { generatorName.set('java') configOptions.set([ library: 'restclient', openApiNullable: 'false' ]) inputSpec = \"${projectDir}\/src\/main\/resources\/petclinic-spec.yml\" outputDir = \"${projectDir}\/build\/generated\/java-rest-client\" ignoreFileOverride.set(\".openapi-generator-java-sources.ignore\") invokerPackage.set('com.myapp') modelPackage.set('com.myapp.model') apiPackage.set('com.myapp.api') } *\/  \/\/web-server openApiGenerate { generatorName = 'spring' configOptions.set([ library: 'spring-boot', openApiNullable: 'false', generateSupportingFiles: 'false', interfaceOnly: 'true', useSpringBoot3: 'true' ]) inputSpec = \"${projectDir}\/src\/main\/resources\/petclinic-spec.yml\" outputDir = \"${projectDir}\/build\/generated\/java-server\" apiPackage = \"com.example.api\" modelPackage = \"com.example.model\" \/\/configOptions = [dateLibrary: \"java8\"] }  sourceSets { main { java { srcDirs(\"$buildDir\/generated\/java-server\/src\/main\/java\")  \/\/server srcDirs(\"$buildDir\/generated\/java-rest-client\/src\/main\/java\") \/\/client } } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">spring.application.name=open-api-demo server.port=8082  #config spring.profiles.active=swagger, actuator, adminClient spring.cloud.config.fail-fast=true spring.cloud.config.uri=http:\/\/localhost:8888 spring.config.import=optional:configserver:http:\/\/localhost:8888 spring.cloud.config.import-check.enabled=true<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430 \u0432\u0440\u0443\u0447\u043d\u0443\u044e<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/de4\/565\/911\/de4565911ef49b74ee5c83131ca56598.png\" width=\"392\" height=\"536\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/de4\/565\/911\/de4565911ef49b74ee5c83131ca56598.png\"\/><\/figure>\n<p>\u041f\u043b\u0430\u0433\u0438\u043d \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u043c, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c, \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0430\u043f\u0438, \u0434\u0442\u043e \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/863\/145\/cdb\/863145cdb32623849d219b48dbb2f996.png\" width=\"351\" height=\"589\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/863\/145\/cdb\/863145cdb32623849d219b48dbb2f996.png\"\/><\/figure>\n<p>\u0410 \u0438\u0441\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0430\u043f\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c (\u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440. \u041a\u043e\u0434 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f)<\/p>\n<pre><code class=\"java\">@SpringBootApplication @RestController public class WebGenerateApplication implements PetsApi {      public static void main(String[] args) {         SpringApplication.run(WebGenerateApplication.class, args);     }       @Override     public ResponseEntity&lt;Pet&gt; getPet(Integer petId) {         Pet pet = new Pet();         pet.setName(\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u044d\u0442\u043e \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440!\");         return ResponseEntity.ok(pet);     }   }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u043b\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 PetsApi \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432.<\/p>\n<p>\u041f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0432\u0430\u0433\u0433\u0435\u0440\u0430 \u0437\u0430\u0439\u0434\u044f \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 <a href=\"http:\/\/localhost:8082\/swagger-ui\/index.html\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:8082\/swagger-ui\/index.html<\/a><br \/>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c \u0432\u0441\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u0430\u043a\u0442\u0438\u0432\u043d\u044b \u0438 \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043b\u0438, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043d\u0430\u0448 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/80d\/229\/dff\/80d229dff3fd7bd5a948fbbc17a75451.png\" width=\"1459\" height=\"327\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/80d\/229\/dff\/80d229dff3fd7bd5a948fbbc17a75451.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3ed\/f1b\/6e5\/3edf1b6e5f3ddef8368257297143c5c9.png\" width=\"856\" height=\"412\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3ed\/f1b\/6e5\/3edf1b6e5f3ddef8368257297143c5c9.png\"\/><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0413\u0435\u0439\u0442\u0432\u0435\u0439<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0433\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0438\u0437 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0443\u0440\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0430\u043f\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438\u0437 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0443\u0440\u0430.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0433\u0435\u0439\u0442\u0432\u0435\u044f \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Spring Cloud Gateway \u0438 \u0432\u0441\u044f \u043d\u0430\u0448\u0430 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441\u0432\u0435\u0434\u0451\u0442\u0441\u044f \u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0433\u0435\u0439\u0442\u0432\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 \u0438\u043b\u0438 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430\u043c\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (\u043d\u043e \u044d\u0442\u043e \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u043d\u0443\u0430\u043b\u0430).<br \/>\u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0435\u0441\u0442\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0442\u0438\u043f\u0430 Spring Cloud Eureka \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043f\u0441\u0435\u0434\u0432\u043e\u043d\u0438\u043c\u044b \u0432\u043c\u0435\u0441\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0445\u043e\u0441\u0442\u043e\u0432 \u0438 \u043f\u043e\u0440\u0442\u043e\u0432. \u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 docker compose \u0438\u043b\u0438, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0442\u0438\u043f\u0430 kubernetes, \u0442\u043e \u0440\u0435\u0435\u0441\u0442\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0432\u0430\u043c \u043a\u0430\u043a \u0431\u044b \u0438 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d. \u0412\u044b \u0438 \u0442\u0430\u043a \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0448\u0438\u043d\u044b \u0441 \u043b\u044e\u0431\u044b\u043c\u0438 \u0434\u043e\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0438\u043c\u0435\u043d\u0430\u043c\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u0432\u043e\u0435\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>build.gradle<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">group = 'ru.gateway' version = '1.0-SNAPSHOT'  dependencies {     \/\/spring     implementation 'org.springframework.cloud:spring-cloud-starter-gateway'     testImplementation 'org.springframework.boot:spring-boot-starter-test'      \/\/swagger(webflux) for gateway     implementation 'org.springdoc:springdoc-openapi-starter-webflux-ui:2.6.0' \/\/https:\/\/www.baeldung.com\/spring-cloud-gateway-integrate-openapi }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>SpringCloudGateway.java<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@SpringBootApplication @EnableScheduling \/\/\u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0437\u0430\u0434\u0430\u0447 \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e. \u041f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435 \u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0434\u043b\u044f \u0430\u043a\u0442\u0438\u0432\u0430\u0442\u043e\u0440\u0430 public class SpringCloudGateway {     public static void main(String[] args) {         SpringApplication.run(SpringCloudGateway.class, args);     } }<\/code><\/pre>\n<p>.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application.yml<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0421\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 &#8212; \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438<br \/>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 springdoc.swagger-ui \u0434\u043b\u044f \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043d\u0438\u044f \u0441\u0432\u0430\u0433\u0433\u0435\u0440\u043e\u0432 \u0432\u0441\u0435\u0445 \u043f\u0440\u0438\u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<br \/>\u0418, \u0440\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 routes \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0441\u0430\u043c\u0443 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044e.<br \/>predicates &#8212; \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043a\u043e\u0433\u0434\u0430 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 (\u0438 \u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e &#171;**&#187; \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 &#171;\u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e \u0434\u0430\u043b\u044c\u0448\u0435, \u043b\u044e\u0431\u043e\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430&#187;)<br \/>uri &#8212; \u043a\u0443\u0434\u0430 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441<br \/>\u0424\u0438\u043b\u044c\u0442\u0440 \u0442\u0438\u043f\u0430 RewritePath \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043c\u0435\u043d\u0443 \u0432 \u0443\u0440\u043b-\u0430\u0434\u0440\u0435\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043e\u0434\u043d\u043e\u0439 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0430 \u0434\u0440\u0443\u0433\u0443\u044e.<\/p>\n<pre><code class=\"yaml\">#web server:   port: 80  management:   endpoint:     health:       show-details: always     info:       enabled: true     shutdown:       enabled: true    #\u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0432\u044b\u043a\u043b\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f curl -i -X POST http:\/\/localhost:80\/actuator\/shutdown     gateway:       enabled: true   endpoints:     web:       exposure:         include: gateway, health, metrics, shutdown, info, myCustomEndpoint    #http:\/\/localhost\/actuator\/gateway\/routes   #http:\/\/localhost\/webjars\/swagger-ui\/index.html?urls.primaryName=gateway-service springdoc:   enable-native-support: true   api-docs:     enabled: true     path: \/api-docs   swagger-ui:     enabled: true     path: \/swagger-ui     urls:       #Gateway(this)       -   name: gateway-service           primaryName: API Gateway Service           url: \/api-docs       #AuthService   http:\/\/localhost\/webjars\/swagger-ui\/index.html?urls.primaryName=auth-service       -   name: auth-service           primaryName: API Auth Service           url: http:\/\/localhost:8079\/api-docs       #WebApplication1  http:\/\/localhost\/webjars\/swagger-ui\/index.html?urls.primaryName=web-app1-service       -   name: web-app1-service           primaryName: API Application 'WebApplication1'           url: http:\/\/localhost:8080\/api-docs       #WebSecurityApplication  http:\/\/localhost\/webjars\/swagger-ui\/index.html?urls.primaryName=web-sec-app-service       -   name: web-sec-app-service           primaryName: API Application 'WebSecurityApplication'           url: http:\/\/localhost:8081\/api-docs       #WebGenerateApplication  http:\/\/localhost\/webjars\/swagger-ui\/index.html?urls.primaryName=web-gen-app-service       -   name: web-gen-app-service           primaryName: API Application 'WebGenerateApplication'           url: http:\/\/localhost:8082\/api-docs  spring:   boot:     admin:       client:         url: http:\/\/localhost:8099   application:     name: Gateway   cloud:     gateway:       httpclient:         ssl:  #\u0434\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0432\u0441\u0435\u043c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430\u043c           useInsecureTrustManager: true       routes: #AuthService  - http:\/\/localhost:80\/AuthService\/login         - id: AuthService-registration           uri: http:\/\/localhost:8079           predicates:             - Path=\/AuthService\/**           filters:             - RewritePath=\/AuthService, \/auth  #WebApplication1         #\u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a http:\/\/localhost:80\/WebApplication1\/web\/hello?name=rrrrr         - id: WebApplication1-web           uri: http:\/\/localhost:8080   #\u0443\u0440\u043b \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043a\u0443\u0434\u0430 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441           predicates:     #\u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f             - Path=\/WebApplication1\/web\/**           filters: #\u043a\u0430\u043a \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u0443\u0442\u0438 \u0442\u0443\u0434\u0430 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e             - RewritePath=\/WebApplication1\/web, \/app\/v1          #\u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a http:\/\/localhost:80\/WebApplication1\/db\/1         - id: WebApplication1-db           uri: http:\/\/localhost:8080           predicates:             - Path=\/WebApplication1\/db\/**           filters:             - RewritePath=\/WebApplication1\/db, \/app\/db\/worker  #WebSecurityApplication   \u043a\u0430\u043a http:\/\/localhost:80\/WebSecurityApplication\/web\/hello1         - id: WebSecurityApplication-web           uri: http:\/\/localhost:8081           predicates:             - Path=\/WebSecurityApplication\/web\/**           filters:             - RewritePath=\/WebSecurityApplication\/web, \/app\/v1  #WebGenerateApplication         - id: WebGenerateApplication-pets           uri: http:\/\/localhost:8082           predicates:             - Path=\/WebGenerateApplication\/**           filters:             - RewritePath=\/WebGenerateApplication, \/  #other         - id: help           uri: https:\/\/spring.io\/guides           predicates:             - Path=\/help           filters:             - RedirectTo=302, https:\/\/spring.io\/guides <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0422\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0433\u0435\u0439\u0442\u0432\u0435\u0439<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0432\u0430\u0433\u0433\u0435\u0440 \u0437\u0430\u0439\u0434\u044f \u043d\u0430 <a href=\"http:\/\/localhost\/swagger-ui\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost\/swagger-ui<\/a>  (\u0438\u043b\u0438 \u0436\u0435 \u043d\u0430 <a href=\"http:\/\/localhost\/webjars\/swagger-ui\/index.html?urls.primaryName=gateway-service\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost\/webjars\/swagger-ui\/index.html?urls.primaryName=gateway-service<\/a>)<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5b8\/89d\/146\/5b889d146816a2d5407276877e9547f7.png\" width=\"1242\" height=\"636\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5b8\/89d\/146\/5b889d146816a2d5407276877e9547f7.png\"\/><\/figure>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u0441\u0432\u0430\u0433\u0433\u0435\u0440 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0440\u043e\u043d\u0442-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f postman \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0430\u043f\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438\u0437 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0443\u0440\u0430 \u043e\u0431\u0440\u0430\u0449\u0430\u044f\u0441\u044c \u043a \u0433\u0435\u0439\u0442\u0432\u0435\u044e \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u0443\u0440\u043b-\u0430\u043c,\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<br \/>\u043d\u0430 <a href=\"http:\/\/localhost:80\/AuthService\/login\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:80\/AuthService\/login<\/a>   \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043f\u043e \u043b\u043e\u0433\u0438\u043d\u0443 \u0438 \u043f\u0430\u0440\u043e\u043b\u044e.<br \/>\u043d\u0430 <a href=\"http:\/\/localhost:80\/WebApplication1\/web\/hello?name=rrrrr\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:80\/WebApplication1\/web\/hello?name=rrrrr<\/a>   \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0445\u043b\u043b\u043e\u0443-\u0430\u043f\u0438 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<br \/>\u043d\u0430 <a href=\"http:\/\/localhost:80\/WebSecurityApplication\/web\/hello1\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:80\/WebSecurityApplication\/web\/hello1<\/a>   \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0430\u043f\u0438 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043c\u0435\u0442\u0440\u0438\u043a\u0443 \u0434\u043b\u044f \u0430\u043a\u0442\u0443\u0430\u0442\u043e\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043c\u0435\u0442\u0440\u0438\u043a\u0443 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 spring actuator \u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0432 \u0441\u043f\u0440\u0438\u043d\u0433-\u0431\u0443\u0442-\u0430\u0434\u043c\u0438\u043d-\u0441\u0435\u0440\u0432\u0435\u0440\u0435<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u044d\u043d\u0434\u043f\u043e\u0439\u043d\u0442\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0442\u044c, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043a\u0430\u043a <a href=\"http:\/\/localhost\/actuator\/myCustomEndpoint\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost\/actuator\/myCustomEndpoint<\/a><\/p>\n<pre><code class=\"java\">package ru.gateway.actuator;  import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.stereotype.Component;  \/**\u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u044d\u043d\u0434\u043f\u043e\u0439\u043d\u0442\u0430 \u0434\u043b\u044f \u0430\u043a\u0442\u0443\u0430\u0442\u043e\u0440\u0430*\/ @Component @Endpoint(id = \"myCustomEndpoint\") public class MyCustomEndpoint {     MyCustomData data=new MyCustomData(101, \"Hello\");      @ReadOperation \/\/GET   http:\/\/localhost\/actuator\/myCustomEndpoint     public MyCustomData getData() {         return data;     }     @WriteOperation \/\/POST     public void writeData(Integer id, String msg) {         data.i=id;         data.s=msg;     }     @DeleteOperation \/\/DELETE     public Integer deleteData() {         data.i=-1;         data.s=\"\";         return 0;     } }  @AllArgsConstructor @NoArgsConstructor @Data class MyCustomData{     Integer i;     String s; }<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1eb\/7ea\/ace\/1eb7eaacee28f839d4bd1cc64d1df224.png\" width=\"327\" height=\"117\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1eb\/7ea\/ace\/1eb7eaacee28f839d4bd1cc64d1df224.png\"\/><\/figure>\n<p>\u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435<br \/>management.endpoints.web.exposure.include: *  \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u043e \u0432\u0441\u0435\u043c \u044d\u043d\u0434\u043f\u043e\u0439\u043d\u0442\u0430\u043c \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0443\u043a\u0430\u0437\u0430\u0432 \u0438 \u043d\u0430\u0448 \u0442\u043e\u0436\u0435 myCustomEndpoint<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u0440\u0438\u043a<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0427\u0442\u043e\u0431\u044b \u043c\u0435\u0440\u0438\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u043b\u0438\u0441\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0448\u0435\u0434\u0443\u043b\u043b\u0435\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0435\u043a\u0443\u043d\u0434\u0443<\/p>\n<pre><code class=\"java\"> \/**\u0428\u0435\u0434\u0443\u043b\u043b\u0435\u0440 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u043a  * https:\/\/habr.com\/ru\/companies\/otus\/articles\/650871\/  * \u0418\u0437 MeterRegistry \u043c\u043e\u0436\u043d\u043e \u0438\u043d\u0441\u0442\u0430\u043d\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0438\u043f\u044b \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u043e\u0432:  * Counter: \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u0445 \u043f\u043e\u0434\u0441\u0447\u0435\u0442\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.  * Gauge: \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u0431\u043e\u0440\u0430  * Timers: \u0438\u0437\u043c\u0435\u0440\u044f\u0435\u0442 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0438\u043b\u0438 \u0447\u0430\u0441\u0442\u043e\u0442\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439  * DistributionSummary: \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0434\u0438\u0441\u0442\u0440\u0438\u0431\u0443\u0446\u0438\u044e \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0438\u0442\u043e\u0433\u043e\u0432\u0443\u044e \u0441\u0432\u043e\u0434\u043a\u0443.*\/ @Component public class MetricScheduler {     private final AtomicInteger testGauge;     private final Counter testCounter;      public MetricScheduler(MeterRegistry meterRegistry) {         \/\/ Counter vs. gauge, summary vs. histogram         \/\/ https:\/\/prometheus.io\/docs\/practices\/instrumentation\/#counter-vs-gauge-summary-vs-histogram         testGauge = meterRegistry.gauge(\"custom_gauge\", new AtomicInteger(0));         testCounter = meterRegistry.counter(\"custom_counter\");     }      @Scheduled(fixedRateString = \"1000\", initialDelayString = \"0\")     public void schedulingTask() {         testGauge.set(getRandomNumberInRange(0, 100));         testCounter.increment();     }      private static int getRandomNumberInRange(int min, int max) {         if (min &gt;= max) {             throw new IllegalArgumentException(\"max must be greater than min\");         }          Random r = new Random();         return r.nextInt((max - min) + 1) + min;     } }<\/code><\/pre>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u043a<br \/><a href=\"http:\/\/localhost\/actuator\/metrics\/custom_gauge\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost\/actuator\/metrics\/custom_gauge<\/a><br \/><a href=\"http:\/\/localhost\/actuator\/metrics\/custom_counter\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost\/actuator\/metrics\/custom_counter<\/a><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/184\/f5a\/565\/184f5a5657284b790b46a15a275d6235.png\" width=\"634\" height=\"107\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/184\/f5a\/565\/184f5a5657284b790b46a15a275d6235.png\"\/><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0441\u043c <a href=\"https:\/\/habr.com\/ru\/companies\/otus\/articles\/650871\/\" rel=\"noopener noreferrer nofollow\"><em>https:\/\/habr.com\/ru\/companies\/otus\/articles\/650871\/<\/em><\/a><\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0441\u043c<br \/><a href=\"https:\/\/tproger.ru\/articles\/pishem-java-veb-prilozhenie-na-sovremennom-steke-s-nulja-do-mikroservisnoj-arhitektury-chast-3\" rel=\"noopener noreferrer nofollow\">https:\/\/tproger.ru\/articles\/pishem-java-veb-prilozhenie-na-sovremennom-steke-s-nulja-do-mikroservisnoj-arhitektury-chast-3<\/a><br \/><a href=\"https:\/\/sysout.ru\/spring-cloud-api-gateway\/?ysclid=m5ergtfz7887528745\" rel=\"noopener noreferrer nofollow\">https:\/\/sysout.ru\/spring-cloud-api-gateway\/?ysclid=m5ergtfz7887528745<\/a><br \/><a href=\"https:\/\/www.concretepage.com\/spring-boot\/spring-cloud-gateway\" rel=\"noopener noreferrer nofollow\">https:\/\/www.concretepage.com\/spring-boot\/spring-cloud-gateway<\/a><br \/><a href=\"https:\/\/cloud.spring.io\/spring-cloud-gateway\/reference\/html\/\" rel=\"noopener noreferrer nofollow\">https:\/\/cloud.spring.io\/spring-cloud-gateway\/reference\/html\/<\/a><\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>SpringBootAdminServer<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u043e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u0439. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u0435\u043d \u043e\u043d \u0442\u0435\u043c, \u0447\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 spring actuator \u0443 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u043c \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u043f\u0440\u0438\u043d\u0433-\u0431\u0443\u0442-\u0430\u0434\u043c\u0438\u043d-\u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430<\/p>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/habr.com\/ru\/articles\/479954\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/articles\/479954\/<\/a><\/p>\n<details class=\"spoiler\">\n<summary>build.gradle<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">group = 'ru.configs' version = '1.0-SNAPSHOT'  dependencies {     \/\/spring     implementation 'org.springframework.boot:spring-boot-starter-web'     \/\/spring boot admin     implementation 'de.codecentric:spring-boot-admin-starter-server:3.1.5'      \/\/add security     \/\/implementation 'org.springframework.boot:spring-boot-starter-security:3.1.5' }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>application.properties<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">spring.application.name=SpringBootAdminServer server.port=8099 #http:\/\/localhost:8099\/applications #http:\/\/localhost:8099\/spring-security-mvc-login\/login.html  #spring.boot.admin.routes.endpoints=env, metrics, trace, jolokia, info, configprops<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430 <a href=\"http:\/\/localhost:8099\/applications\" rel=\"noopener noreferrer nofollow\">http:\/\/localhost:8099\/applications<\/a> \u0438 \u0432\u0438\u0434\u0438\u043c \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b.<br \/>\u041c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u043f\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9f4\/37e\/b82\/9f437eb82321d1132401902be80c6ecb.png\" width=\"1674\" height=\"627\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9f4\/37e\/b82\/9f437eb82321d1132401902be80c6ecb.png\"\/><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u0434\u0443\u043c\u044b\u0432\u0430\u043b\u0430\u0441\u044c \u043a\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0441 \u043d\u0443\u043b\u044f \u0432 \u0441\u0436\u0430\u0442\u044b\u0435 \u0441\u0440\u043e\u043a\u0438.<\/p>\n<p>\u0414\u043e\u0440\u043e\u0433\u043e\u0439 \u0434\u0440\u0443\u0433, \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0435\u0451 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u044a\u0451\u043c \u043d\u0435 \u0443\u0442\u043e\u043c\u0438\u043b \u0442\u0435\u0431\u044f \u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u044b \u0434\u0430\u0436\u0435 \u0441\u0443\u043c\u0435\u043b \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435 \u0434\u043b\u044f \u0441\u0435\u0431\u044f.<\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438: <a href=\"https:\/\/github.com\/upswet\/SimpleSpringExample\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/upswet\/SimpleSpringExample<\/a><\/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\/articles\/872776\/\"> https:\/\/habr.com\/ru\/articles\/872776\/<\/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>\u0414\u043e\u0440\u043e\u0433\u043e\u0439 \u0434\u0440\u0443\u0433, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c \u0447\u0442\u043e \u0442\u044b \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440 (\u0430 \u0442\u0430\u043a\u0436\u0435 \u0431\u044d\u043a \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0444\u0440\u043e\u043d\u0442-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 \u043e\u0434\u043d\u043e\u043c \u043b\u0438\u0446\u0435) \u0438 \u043e\u0442 \u0442\u0435\u0431\u044f \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u044d\u0442\u0438\u043c \u0438 \u0437\u0430\u0439\u043c\u0451\u043c\u0441\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044f \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044f\u043c\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043d\u0430 \u043f\u0440\u043e\u0434-\u0441\u0442\u0435\u043d\u0434\u0435.<\/p>\n<p>\u0422\u043e\u0447\u043d\u0435\u0435, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438 \u0443\u0432\u044f\u0436\u0435\u043c \u0432 \u0435\u0434\u0438\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443<\/p>\n<ul>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 (AuthService) \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 oauth 2.0 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u044b \u043a \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 (SpringCloudConfig) \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0441\u0435\u043c \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438. \u0422\u0430\u043a\u0436\u0435 \u043e\u043d \u0434\u0430\u0441\u0442 \u043d\u0430\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\/\u0438\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0413\u0435\u0439\u0442\u0432\u0435\u0439 (SpringCloudGateway) \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438\u0437 \u0443\u0441\u043b\u043e\u0432\u043d\u043e \u043d\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u0437\u043e\u043d\u044b \u0432 \u0443\u0441\u043b\u043e\u0432\u043d\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u0437\u043e\u043d\u0443 \u0433\u0434\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 (SpringBootAdminServer) \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 1 (WebApplication) \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u043e\u0439 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441 \u0441 \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a \u0411\u0414 \u0438 \u0440\u0443\u0447\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0440\u0432\u0435\u0440-\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 2 (WebSecurityApplication) \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u043e\u0439 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441 \u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b spring security<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 3 (WebGenerateApplication) \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u043e \u0437\u0430\u0442\u043e \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430 &#171;api first&#187; \u0438 \u0430\u0432\u0442\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><\/figure>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431: <a href=\"https:\/\/github.com\/upswet\/SimpleSpringExample\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/upswet\/SimpleSpringExample<\/a><\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0438 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b<\/p>\n<ul>\n<li>\n<p>Spring: spring web, spring data, spring security (\u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e), spring actuator, spring cloud config, spring cloud gateway, spring boot admin<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 oauth 2 (\u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e)<\/p>\n<\/li>\n<li>\n<p>api-first (\u0441 \u0430\u0432\u0442\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u043a\u043e\u0434\u0430 \u0447\u0435\u0440\u0435\u0437 org.openapi.generator)<\/p>\n<\/li>\n<li>\n<p>gradle<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u043a\u0430\u043a \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0438\u043b\u0438 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435.<br \/>\u0417\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u0442\u0430\u043a\u0438\u0435 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0432\u0435\u0449\u0438, \u043a\u0430\u043a<\/p>\n<ul>\n<li>\n<p>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 \u0431\u0440\u043e\u043a\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 Apache Kafka<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u0435\u0441\u0442\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 spring cloud eureka. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u0440\u0438\u0441\u043a\u043d\u0443 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0442\u044c \u0447\u0442\u043e \u043e\u043d \u0432\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0434\u043e\u043a\u043a\u0435\u0440-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0438 \u0445\u043e\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0445\u043e\u0442\u044f \u0431\u044b \u0434\u0430\u0436\u0435 docker compose), \u0430 \u043b\u0443\u0447\u0448\u0435 \u0447\u0442\u043e \u0442\u0438\u043f\u0430 kubernetes<\/p>\n<\/li>\n<li>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u043b\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 spring security (\u043e\u0434\u043d\u0430\u043a\u043e \u044f \u043d\u0430\u0441\u0442\u0430\u0438\u0432\u0430\u044e, \u0447\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u043d\u0438\u0436\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u043f\u043e\u043b\u043d\u0435 \u043d\u0430\u0434\u0451\u0436\u043d\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430. \u0422\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u0435\u0441\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u043b\u043e\u0442\u043d\u043e \u0441\u0435\u0442\u044c \u043d\u0430 \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441\u043f\u0440\u0438\u043d\u0433-\u0441\u0435\u043a\u044c\u044e\u0440\u0438\u0442\u0438, \u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u043b\u0435\u0437\u0442\u044c \u0441 \u043d\u0435\u0451 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f). \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u044d\u0442\u043e \u0434\u0438\u0441\u043a\u0443\u0441\u0441\u0438\u043e\u043d\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041e\u0442\u043a\u0430\u0437 \u043e\u0442 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043d\u0430 \u0441\u0432\u043e\u0439 \u0440\u0438\u0441\u043a \u0438 \u0441\u0442\u0440\u0430\u0445 \u0438 \u0432\u0441\u0451 \u0442\u0430\u043a\u043e\u0435.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0439. \u041f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u0432\u0435\u0437\u0434\u0435 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0434\u0443\u043c\u0447\u0438\u0432\u043e\u0433\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u043c.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043d\u043e\u0433\u043e\u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u0439 gradle-\u043f\u0440\u043e\u0435\u043a\u0442<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c \u0442\u0435\u043e\u0440\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u0434\u043b\u0435-\u043f\u0440\u0435\u043e\u043a\u0442\u043e\u0432 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 <a href=\"https:\/\/www.book2s.com\/tutorials\/gradle-dependency-management.html\" rel=\"noopener noreferrer nofollow\">https:\/\/www.book2s.com\/tutorials\/gradle-dependency-management.html<\/a><\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u043e\u043c\u043e\u043b\u044f\u0441\u044c <a href=\"https:\/\/internat.msu.ru\/about\/istoriya\/kolmogorov\/\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043b\u043c\u043e\u0433\u043e\u0440\u043e\u0432\u0443 <\/a>\u0438 <a href=\"https:\/\/habr.com\/ru\/companies\/ua-hosting\/articles\/370259\/\" rel=\"noopener noreferrer nofollow\">\u0413\u043b\u0443\u0448\u043a\u043e<\/a>, \u043d\u0430\u0447\u043d\u0451\u043c \u043f\u043e\u0442\u0438\u0445\u043e\u043d\u044c\u043a\u0443<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043c\u0443\u043b\u044c\u0442\u0438\u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 SimpleSpring<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0444\u0430\u0439\u043b\u044b <\/p>\n<p><strong>settings.gradle<\/strong> &#8212; \u0432 \u043d\u0451\u043c \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043d\u0430\u0448\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043d\u0430\u0448\u0435\u0433\u043e &#171;\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e&#187; \u043f\u0440\u043e\u0435\u043a\u0442\u0430<br \/>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0442\u0443\u0434\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u0447\u043a\u0443 &#8212; \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 &#171;\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e&#187; \u043f\u0440\u043e\u0435\u043a\u0442\u0430<br \/><em>rootProject.name = &#8216;SpringSimple&#8217;<\/p>\n<p><\/em>\u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0430\u0439\u043b <strong>build.gradle<\/strong> &#8212; \u0432 \u043d\u0451\u043c \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438<\/p>\n<details class=\"spoiler\">\n<summary>\u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 build.gradle<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">\/*\u0423\u043a\u0430\u0436\u0435\u043c \u043a\u0430\u043a\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c (\u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b, \u043d\u043e \u043d\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b)*\/ plugins {     id 'java'     id 'org.springframework.boot' version '3.3.1'     id 'io.spring.dependency-management' version '1.1.5'     id 'org.openapi.generator' version '7.10.0' }  \/*\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044e\u0449\u0443\u044e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u0415\u0441\u043b\u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e, \u0442\u043e \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043d\u0438\u0436\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 lombok*\/ configurations {     compileOnly {         extendsFrom annotationProcessor     } }  \/*\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438, \u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0442\u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u0430\u0447\u0435\u043d\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0417\u0434\u0435\u0441\u044c \u0443\u043a\u0430\u0437\u0430\u043d \u043e\u0431\u0449\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439.*\/ repositories {     mavenCentral() }  \/*\u0412 \u044d\u0442\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u044b. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u0441\u0451, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u043e \u043a \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u0435\u043c \u0447\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0415\u0413\u041e \u043b\u0438\u0447\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 build.gradle.*\/ subprojects {     \/*\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u0442\u0440\u0438 \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u0441\u043a\u0430\u0447\u0435\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432.   \u041f\u043e\u0447\u0435\u043c\u0443 \u043d\u0435 \u0432\u0441\u0435 \u0447\u0435\u0442\u044b\u0440\u0435 \u0441\u0440\u0430\u0437\u0443? \u041f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0447\u0435\u0442\u0432\u0451\u0440\u0442\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d \u043d\u0443\u0436\u0435\u043d \u043d\u0435 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0435.   \u0422\u0430\u043c \u0433\u0434\u0435 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043d\u0443\u0436\u0435\u043d, \u043c\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u0435\u0433\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e.*\/     apply plugin: 'java'     apply plugin: 'org.springframework.boot'     apply plugin: 'io.spring.dependency-management'      \/*\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 (\u043a\u0440\u043e\u043c\u0435 \u043e\u0431\u0449\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0448\u0435). \u041d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \"\u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439\", \u0442\u043e \u0435\u0441\u0442\u044c \u0432\u0441\u0435 jar-\u0444\u0430\u0439\u043b\u044b \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0432 \u043f\u0430\u043f\u043a\u0443 libs \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0430       \u0417\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e? \u041d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043d\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u044f \u0435\u0451 \u0438\u0437 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f*\/     repositories {         mavenCentral()         flatDir {             dirs 'libs'         }     }      \/*\u041e\u0431\u044a\u044f\u0432\u0438\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041d\u0430\u043f\u043e\u043c\u043d\u0438\u044e \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0442\u0430\u043a \u043a\u0430\u043a \u0443\u0430\u0437\u0430\u043d\u044b \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438 subprojects*\/     dependencies {         \/\/\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 PostConstructor         implementation 'javax.annotation:javax.annotation-api:1.3.2'          \/\/\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 jwt-\u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438.          implementation 'com.auth0:java-jwt:3.18.2'          \/\/\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u043e\u0432\u0430\u043d\u0438\u044f spring actuator \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c  https:\/\/www.concretepage.com\/spring-boot\/spring-boot-actuator-endpoints, https:\/\/www.book2s.com\/tutorials\/spring-boot-actuator.html         \/*\u0415\u0441\u043b\u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e, \u0442\u043e spring actuator \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0435 \u0430\u043f\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u043c\u0440\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438*\/                   implementation 'org.springframework.boot:spring-boot-starter-actuator'          \/\/spring admin client         \/\/\u041a\u043b\u0438\u0435\u043d\u0442 \u043a \u0441\u0435\u0440\u0432\u0438\u0441\u0443 \u0441\u043f\u0440\u0438\u043d\u0433-\u0431\u0443\u0442-\u0430\u0434\u043c\u0438\u043d \u0430\u043a\u043a\u0430\u043c\u0443\u043b\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u0443\u044e \u0438\u043c \u0447\u0435\u0440\u0435\u0437 spring actuator         implementation 'de.codecentric:spring-boot-admin-starter-client:3.1.5'          \/\/swagger         \/\/\u041e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0438\u0436\u0435         implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0' \/\/\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c https:\/\/www.baeldung.com\/spring-rest-openapi-documentation          \/\/spring cloud config         \/\/\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0441 \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0422\u043e \u0435\u0441\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442 \u043a \u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0438\u0441\u0443         implementation 'org.springframework.cloud:spring-cloud-starter-config'         implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'          \/\/lombok         \/*\u041a\u0440\u0430\u0439\u043d\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441\u0438\u043b\u044c\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0448\u0430\u044e\u0449\u0430\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430 \u043f\u0443\u0442\u0451\u043c \u0430\u0432\u0442\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u043e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f\u043c.           \u0418\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0439 \u0442\u0440\u0435\u0431\u0443\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u0435\u0440\u0435\u0434 \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0435\u0439*\/         compileOnly 'org.projectlombok:lombok:1.18.30'         annotationProcessor 'org.projectlombok:lombok:1.18.30'         testCompileOnly 'org.projectlombok:lombok'         testAnnotationProcessor 'org.projectlombok:lombok'     }     \/\/\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c (\u0438 \u0437\u0430\u0442\u0435\u043c \u0438\u0441\u043f\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438) \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u0441\u043f\u0440\u0438\u043d\u0433\u043e\u0432\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438     ext {         set('springCloudVersion', \"2023.0.1\")     }     dependencyManagement {         imports {             mavenBom \"org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}\"         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u044d\u0442\u043e\u0433\u043e \u0443\u0436\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. <br \/>\u041e\u0442\u043a\u0440\u043e\u0435\u043c \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 \u0441\u0440\u0435\u0434\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 IntelliJ IDEA (\u0434\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0434\u0435\u044f) \u0438 \u043e\u043d\u0430, \u043f\u043e\u043d\u044f\u0432 \u0447\u0442\u043e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0433\u0440\u0430\u0434\u043b\u0435-\u043f\u0440\u043e\u0435\u043a\u0442, \u0441\u0430\u043c\u0430 \u0441\u043a\u0430\u0447\u0430\u0435\u0442 \u0433\u0440\u0430\u0434\u043b\u0435-\u0432\u0440\u0430\u043f\u0435\u0440 \u0438 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<br \/>\u0427\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 (\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0433\u0440\u0430\u0434\u043b\u0435 \u0438 \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438) \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/www.book2s.com\/tutorials\/gradle-install.html\" rel=\"noopener noreferrer nofollow\">\u043c\u0430\u043d\u0443\u0430\u043b\u043e\u043c<\/a>.<\/p>\n<p>\u041e\u043f\u044f\u0442\u044c \u0436\u0435, \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0441\u043c \u0432\u043e\u0442 \u044d\u0442\u0443 <a href=\"https:\/\/www.book2s.com\/tutorials\/gradle-multi-project.html\" rel=\"noopener noreferrer nofollow\">\u0433\u043b\u0430\u0432\u0443 <\/a>\u043c\u0430\u043d\u0443\u0430\u043b\u0430<\/p>\n<details class=\"spoiler\">\n<summary>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0447\u0442\u043e\u0431\u044b \u043e\u0434\u043d\u0438 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441\u0430\u043c \u0431\u044b\u043b \u0431\u044b \u043c\u043d\u043e\u0433\u043e\u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c. \u0418\u043b\u0438 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0448\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432 \u0433\u0440\u0443\u043f\u043f\u0443?<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u0435\u0440\u0432\u0438\u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 (SpringCloudConfig)<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0432\u0441\u0435\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u0433\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u043e\u043f\u0440\u043e\u0441\u044f\u0442.<\/p>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0434\u0435\u0441\u044c:<br \/><a href=\"https:\/\/sysout.ru\/spring-cloud-configuration-server\/\" rel=\"noopener noreferrer nofollow\">https:\/\/sysout.ru\/spring-cloud-configuration-server\/<\/a><br \/><a href=\"https:\/\/www.czetsuyatech.com\/2019\/10\/spring-config-using-git.html\" rel=\"noopener noreferrer nofollow\">https:\/\/www.czetsuyatech.com\/2019\/10\/spring-config-using-git.html<\/a><br \/><a href=\"https:\/\/docs.spring.io\/spring-cloud-config\/docs\/current\/reference\/html\/\" rel=\"noopener noreferrer nofollow\">https:\/\/docs.spring.io\/spring-cloud-config\/docs\/current\/reference\/html\/<\/a><br \/><a href=\"https:\/\/www.baeldung.com\/spring-cloud-config-without-git\" rel=\"noopener noreferrer nofollow\">https:\/\/www.baeldung.com\/spring-cloud-config-without-git<\/a><\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0441\u0438\u0432 \u0443\u0434\u0430\u0447\u0438 \u0443 <a href=\"https:\/\/ru.ruwiki.ru\/wiki\/%D0%91%D1%80%D1%83%D0%B4%D0%BD%D0%BE,_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80_%D0%9B%D1%8C%D0%B2%D0%BE%D0%B2%D0%B8%D1%87\" rel=\"noopener noreferrer nofollow\">\u0411\u0440\u0443\u0434\u043d\u043e <\/a>\u043f\u0440\u0438\u043c\u0435\u043c\u0441\u044f \u0437\u0430 \u0434\u0435\u043b\u043e<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 SpringCloudConfig \u0432\u043d\u0443\u0442\u0440\u0438 SpringSimple \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043d\u0438\u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435<\/p>\n<p>SpringSimple\/<br \/> \u2502<br \/> \u251c\u2500\u2500 build.gradle<br \/> \u251c\u2500\u2500 settings.gradle<br \/> \u2502<br \/> \u251c\u2500\u2500 SpringCloudConfig\/<br \/> \u2502   \u251c\u2500\u2500 build.gradle<br \/> \u2502   \u251c\u2500\u2500 git-local-repo\/<br \/> \u2502   \u2502         \u251c\u2500\u2500 * (\u043a\u0443\u0441\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432)<br \/> \u2502   \u2514\u2500\u2500 src\/<br \/> \u2502       \u251c\u2500\u2500 main\/<br \/> \u2502       \u2502     \u251c\u2500\u2500 java\/<br \/> \u2502       \u2502     \u2502    \u251c\u2500\u2500 ru\/<br \/> \u2502       \u2502     \u2502    \u2502    \u251c\u2500\u2500 configs\/<br \/> \u2502       \u2502     \u2502    \u2502    \u2502    \u251c\u2500\u2500 SpringCloudConfig.java<br \/> \u2502       \u2502     \u251c\u2500\u2500 resources\/<br \/> \u2502       \u2502     \u2502     \u251c\u2500\u2500application.properties<br \/> \u2502       \u2514\u2500\u2500 test\/<\/p>\n<p>\u0433\u0434\u0435 git-local-repo &#8212; \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0433\u0438\u0442-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 (\u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433) \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u043a\u0443\u0441\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0448 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 \u0444\u0430\u0439\u043b SpringSimple\\settings.gradle \u043a\u0430\u043a <em>include &#8216;SpringCloudConfig&#8217;<\/em> <\/p>\n<details class=\"spoiler\">\n<summary>build.gradle<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0417\u0434\u0435\u0441\u044c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (\u043f\u043e\u043c\u043d\u0438\u043c \u0447\u0442\u043e \u043a \u043d\u0438\u043c \u0434\u043e\u0431\u0430\u0432\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (SimpleSpring\\build.gradle))<\/p>\n<pre><code class=\"java\">\/\/\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0438 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 jar-\u0444\u0430\u0439\u043b\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 group = 'ru.configs' version = '1.0-SNAPSHOT'  dependencies {     \/\/\u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u043d\u0443 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \"\u043a\u043e\u043d\u0444\u0438\u0433-\u0441\u0435\u0440\u0432\u0435\u0440\"     implementation 'org.springframework.cloud:spring-cloud-config-server' }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>SpringCloudConfig.java<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package ru.configs;  import org.springframework.boot.SpringApplication; import<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\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-444695","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/444695","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=444695"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/444695\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=444695"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=444695"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=444695"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}