{"id":3157,"date":"2020-11-29T18:34:01","date_gmt":"2020-11-29T21:34:01","guid":{"rendered":"https:\/\/devkico.itexto.com.br\/?p=3157"},"modified":"2020-11-29T18:34:03","modified_gmt":"2020-11-29T21:34:03","slug":"entenda-as-configuracoes-do-spring-boot","status":"publish","type":"post","link":"https:\/\/devkico.itexto.com.br\/?p=3157","title":{"rendered":"Entenda as configura\u00e7\u00f5es do Spring Boot!"},"content":{"rendered":"\n<p>Spring Boot \u00e9 uma ferramenta maravilhosa, mas se voc\u00ea n\u00e3o entender como suas configura\u00e7\u00f5es funcionam, a\u00ed voc\u00ea tem um problema. A esmagadora maioria das dificuldades que vejo as pessoas enfrentarem com o framework \u00e9 justamente neste ponto, sendo assim resolvi escrever este post pra dar minha contribui\u00e7\u00e3o.<\/p>\n\n\n\n<p>Neste post vou tratar de tr\u00eas assuntos que s\u00e3o normalmente a fonte da maior parte das confus\u00f5es:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Vamos entender os principais conceitos que envolvem as configura\u00e7\u00f5es.<\/li><li>Em que ordem as configura\u00e7\u00f5es s\u00e3o carregadas e como voc\u00ea pode atuar aqui no momento em que for implantar ou executar sua aplica\u00e7\u00e3o baseada em Spring Boot.<\/li><li>Aquelas que considero boas pr\u00e1ticas na gest\u00e3o de configura\u00e7\u00f5es com Spring Boot.<\/li><\/ul>\n\n\n\n<p>Vai ser um post longo, pois a ideia \u00e9 que sirva de refer\u00eancia no futuro. :)<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Conceitos essenciais<\/h1>\n\n\n\n<figure class=\"wp-block-image alignwide\"><img decoding=\"async\" src=\"https:\/\/mymodernmet.com\/wp\/wp-content\/uploads\/2018\/08\/school-of-athens-raphael-2.jpg\" alt=\"The Story Behind Raphael's Masterpiece 'The School of Athens'\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Sabe aonde mora a maior parte das d\u00favidas relativas a este tema? Aus\u00eancia de conhecimento conceitual. Vamos dar nomes \u00e0s coisas aqui pra tornar nossa vida mais f\u00e1cil. Iremos percorrer tr\u00eas andares deste edif\u00edcio conceitual para que voc\u00ea possa ver desde os pontos mais elementares at\u00e9 os mais abstratos.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Primeiro andar: Java<\/h2>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2009\/10\/java_logo_2.png\" alt=\"Java\" class=\"wp-image-512\" width=\"165\" height=\"219\" srcset=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2009\/10\/java_logo_2.png 250w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2009\/10\/java_logo_2-225x300.png 225w\" sizes=\"(max-width: 165px) 100vw, 165px\" \/><\/figure><\/div>\n\n\n\n<p>Em Java voc\u00ea tem diversas fontes para suas configura\u00e7\u00f5es: arquivos de prorpriedades (properties), vari\u00e1veis de ambiente, vari\u00e1veis de sistema&#8230; Responda rapidamente, olhando o Javadoc da classe java.lang.System, voc\u00ea consegue explicar de forma imediata a diferen\u00e7a entre os m\u00e9todos getenv() e getProperty()?<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"139\" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2020\/11\/image.png\" alt=\"javadoc da classe java.lang.System\" class=\"wp-image-3158\" srcset=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2020\/11\/image.png 840w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2020\/11\/image-300x50.png 300w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2020\/11\/image-768x127.png 768w\" sizes=\"(max-width: 840px) 100vw, 840px\" \/><\/figure>\n\n\n\n<p>O nome dos m\u00e9todos j\u00e1 inicia uma pequena confus\u00e3o: por que &#8220;getenv&#8221; e n\u00e3o &#8220;getEnv&#8221;? O primeiro conceito ent\u00e3o a tratar ser\u00e1 a diferen\u00e7a entre &#8220;environment variable&#8221; (vari\u00e1vel de ambiente) e &#8220;system property&#8221; (propriedade do sistema). <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Vari\u00e1veis de ambiente<\/h3>\n\n\n\n<p>Vari\u00e1vel de ambiente \u00e9 aquela que voc\u00ea define no sistema operacional em que seu c\u00f3digo \u00e9 executado. No caso do Linux (e macOS) o fazemos com os comandos <a href=\"https:\/\/linuxize.com\/post\/how-to-set-and-list-environment-variables-in-linux\/\">set e export<\/a>. J\u00e1 no caso do Windows \u00e9 com o comando set (mais comum) ou a partir do utilit\u00e1rio de configura\u00e7\u00e3o gr\u00e1fica de ambiente, tal como na imagem abaixo:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.computerhope.com\/issues\/pictures\/win10-envirvariables.jpg\" alt=\"Vari\u00e1veis de ambiente no Windows\" width=\"195\" height=\"214\"\/><\/figure><\/div>\n\n\n\n<p>Vamos ent\u00e3o a um exemplo bem simples: imagine que estou no Linux e usando o comando export eu defina a vari\u00e1vel de ambiente <em>nome<\/em> com o valor <em>Kico<\/em>, tal como no script a seguir:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">export nome=Kico<\/pre>\n\n\n\n<p>E na sequ\u00eancia eu tenha o seguinte c\u00f3digo Java:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">System.out.println(System.getenv(\"nome\");<\/pre>\n\n\n\n<p>A sa\u00edda ser\u00e1&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Kico<\/pre>\n\n\n\n<p>Resumindo: temos aqui vari\u00e1veis do sistema operacional que s\u00e3o <strong><em>completamente externas ao nosso c\u00f3digo.<\/em><\/strong> Quer ser aprofundar no tema envolvendo Java? Este \u00e9 <a href=\"https:\/\/docs.oracle.com\/javase\/tutorial\/essential\/environment\/env.html\">o link<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Propriedades do sistema<\/h3>\n\n\n\n<p>Aqui mora a confus\u00e3o. Propriedades do sistema (System Properties) s\u00e3o configura\u00e7\u00f5es que toda aplica\u00e7\u00e3o Java mant\u00e9m em mem\u00f3ria que dizem respeito ao seu ambiente de execu\u00e7\u00e3o. Algumas destas propriedades s\u00e3o padr\u00e3o como, por exemplo, &#8220;user.home&#8221;, que diz qual o diret\u00f3rio home do usu\u00e1rio, &#8220;os.name&#8221;, que diz qual o sistema operacional no qual a aplica\u00e7\u00e3o est\u00e1 sendo executada, etc.<\/p>\n\n\n\n<p>Estas propriedades s\u00e3o portanto impl\u00edcitas (como as que mencionei acima) ou expl\u00edcitas. As expl\u00edcitas s\u00e3o aquelas  que passamos para o comando java usando argumentos que come\u00e7am com &#8220;-D&#8221;. Imagine que eu tenha um programa Java tal como o apresentado a seguir:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>public class Programa {\n     public static void main(String args[]) {\n            System.out.println(System.getProperty(\"nome\"));\n     }\n}<\/code><\/pre>\n\n\n\n<p>Compilado meu programa, e executando-o com o comando abaixo, a sa\u00edda ser\u00e1 &#8220;Kico&#8221;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">java <strong>-Dnome=Kico<\/strong> Programa<\/pre>\n\n\n\n<p>Ent\u00e3o, simplificando, as<strong> propriedades do sistema s\u00e3o as impl\u00edcitas da plataforma de execu\u00e7\u00e3o e aquelas que passamos por linha de comando ao nosso programa Java<\/strong>. Quer se aprofundar no assunto e conhecer as propriedades padr\u00e3o? Este \u00e9 <a href=\"https:\/\/docs.oracle.com\/javase\/tutorial\/essential\/environment\/sysprop.html\">o link<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Segundo andar: Spring<\/h2>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2010\/11\/spring_logo.gif\" alt=\"Spring\" class=\"wp-image-860\" width=\"258\" height=\"172\" srcset=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2010\/11\/spring_logo.gif 432w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2010\/11\/spring_logo-300x200.gif 300w\" sizes=\"(max-width: 258px) 100vw, 258px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Propriedades (Properties)<\/h3>\n\n\n\n<p>Do ponto de vista de quem usa o Spring n\u00e3o h\u00e1 vari\u00e1veis de ambiente ou propriedades do sistema, <strong>h\u00e1 apenas propriedades (Properties)<\/strong>. Uma propriedade \u00e9 uma informa\u00e7\u00e3o de configura\u00e7\u00e3o no formato chave\/valor. Toda propriedade portanto \u00e9 identificada por uma chave e possui um valor associado a esta.<\/p>\n\n\n\n<p>Pense no conceito de property (usarei o termo em ingl\u00eas daqui pra frente pois \u00e9 o que voc\u00ea encontrar\u00e1 na esmagadora maioria das documenta\u00e7\u00f5es e literatura relacionada) como a unidade mais fundamental de configura\u00e7\u00e3o no Spring. O objetivo das abstra\u00e7\u00f5es sobre as quais falarei a respeito agora tem como objetivo obter estas informa\u00e7\u00f5es e organiz\u00e1-las para voc\u00ea.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Environment (Ambiente)<\/h3>\n\n\n\n<p>Esta abstra\u00e7\u00e3o consiste em uma <a href=\"https:\/\/docs.spring.io\/spring-framework\/docs\/5.3.1\/javadoc-api\/org\/springframework\/core\/env\/Environment.html\">interface<\/a> do container Spring que ser\u00e1 usada para modelar outro aspecto fundamental do framework: os perfis (profiles). Antes de falarmos sobre esta outra abstra\u00e7\u00e3o \u00e9 importante refletir um pouco sobre o que v\u00eam a ser um Environment.<\/p>\n\n\n\n<p>O Environment representa na pr\u00e1tica o ambiente de execu\u00e7\u00e3o da sua aplica\u00e7\u00e3o. \u00c9 ele que diz quais vari\u00e1veis de ambiente estamos usando, quais beans dever\u00e3o ser instanciados e tamb\u00e9m quais os perfis que est\u00e3o ativos ou que ser\u00e3o ativados pela nossa aplica\u00e7\u00e3o. Antes de falar sobre os perfis \u00e9 importante mencionar um elemento bastante usado por este componente: a <em>property source<\/em>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Property Source<\/h3>\n\n\n\n<p>Sua fun\u00e7\u00e3o consiste em representar uma fonte de dados da qual iremos obter nossas listas de propriedades. Esta fonte de dados pode ser literalmente qualquer coisa: arquivos, web services, bancos de dados, sistemas gestores de configura\u00e7\u00e3o como o <a href=\"https:\/\/cloud.spring.io\/spring-cloud-config\/reference\/html\/\">Spring Cloud Config Server<\/a>, etc.<\/p>\n\n\n\n<p>Em aplica\u00e7\u00f5es Spring Boot quando desejamos externalizar o acesso aos arquivos de configura\u00e7\u00e3o usamos a anota\u00e7\u00e3o <a href=\"https:\/\/docs.spring.io\/spring-framework\/docs\/current\/javadoc-api\/org\/springframework\/context\/annotation\/PropertySource.html\">@PropertySource<\/a> tal como no exemplo a seguir:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>@PropertySource(\"file:\/\/\/home\/kicolobo\/configsfelizes.properties\")<\/strong>\npublic class AplicacaoSpringBoot {\n  ...\n}<\/pre>\n\n\n\n<p>E, claro, caso nenhuma das op\u00e7\u00f5es providas pelo framework n\u00e3o lhe atendam, basta que voc\u00ea implemente o seu pr\u00f3prio Property Source e registrando-o no Spring, o que foge do assunto deste post.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Profiles (Perfis) &#8211; <strong>muita aten\u00e7\u00e3o aqui!<\/strong><\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/images.pexels.com\/photos\/1093087\/pexels-photo-1093087.jpeg?auto=compress&amp;cs=tinysrgb&amp;h=750&amp;w=1260\" alt=\"Foto profissional gr\u00e1tis de adulto, alvorecer, amanhecer\" width=\"233\" height=\"349\"\/><\/figure><\/div>\n\n\n\n<p>Uma aplica\u00e7\u00e3o Spring Boot ao ser executada pode ter n perfis, mas o que \u00e9 um perfil? O profile identifica um conjunto de configura\u00e7\u00f5es que definem como a sua aplica\u00e7\u00e3o deve se portar em um dado ambiente de execu\u00e7\u00e3o. \u00c9 muito importante aqui saber a diferen\u00e7a entre profiles e ambientes de execu\u00e7\u00e3o, pois muitas vezes estes s\u00e3o usados de modo intercambi\u00e1vel:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Ambiente de execu\u00e7\u00e3o<\/strong> &#8211; onde sua aplica\u00e7\u00e3o est\u00e1 sendo executada. Exemplo: ambiente de desenvolvimento, execu\u00e7\u00e3o de testes, produ\u00e7\u00e3o, homologa\u00e7\u00e3o, etc.<\/li><li><strong>Profile (Perfil)<\/strong> &#8211; um conjunto l\u00f3gico de configura\u00e7\u00f5es que define <strong>como sua aplica\u00e7\u00e3o ir\u00e1 ser executada.<\/strong><\/li><\/ul>\n\n\n\n<p>Ent\u00e3o voc\u00ea pode, por exemplo, ter perfis que identifiquem o tipo de persist\u00eancia que seu projeto est\u00e1 usando. <strong>Exemplo<\/strong>: um perfil chamado <em>Relacional<\/em> que indica que estamos usando datasources contra uma base de dados relacional e outro chamado <em>NoSQL<\/em> que indica que estamos usando bases de dados n\u00e3o relacionais.<\/p>\n\n\n\n<p>E voc\u00ea pode ter este mesmo perfil aplicado a diferentes ambientes de execu\u00e7\u00e3o: imagine o perfil <em>NoSQL<\/em> aplicado aos ambientes de Produ\u00e7\u00e3o e Desenvolvimento, enquanto o perfil <em>Relacional<\/em> apenas no ambiente de homologa\u00e7\u00e3o.<\/p>\n\n\n\n<p>Voltando ao exemplo dos profiles <em>NoSQL<\/em> e <em>Relacional<\/em>, \u00e9 <strong>fundamental saber<\/strong> que <strong>o Profile n\u00e3o indica apenas o conjunto de propriedades (<em>properties<\/em>) que ir\u00e3o ser carregadas, mas tamb\u00e9m quais <em>beans<\/em> ser\u00e3o instanciados<\/strong>. Voltando ao exemplo, podemos ter configura\u00e7\u00f5es de DAO implementadas tal como no exemplo a seguir:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>@Configuration<\/strong>\npublic class ConfiguracaoDAO {\n    @Bean <strong>@Profile(\"Relacional\")<\/strong>\n     public DAOUsuario   getDAORelacional() {\n          return new DAOUsuarioMySQL();\n      }\n\n     @Bean <strong>@Profile(\"NoSQL\")<\/strong>\n      public DAOUsuario getDAONaoRelacional() {\n            return new DAOUsuarioMongoDB()\n       }\n}<\/pre>\n\n\n\n<p>Programando contra interfaces a classe cliente nem sonha que <em>DAOUsuario<\/em> \u00e9 usado contra o MongoDB ou MySQL, mantemos assim a boa pr\u00e1tica de programar contra interfaces e n\u00e3o implementa\u00e7\u00f5es.<\/p>\n\n\n\n<p>Mas a\u00ed voc\u00ea me pergunta: como eu defino o profile adotado?<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Selecionando os profiles<\/h4>\n\n\n\n<h5 class=\"wp-block-heading\">Por system property<\/h5>\n\n\n\n<p>\u00c9 f\u00e1cil, e aqui entra aqueles pontos que voc\u00ea deve <strong>decorar<\/strong>. Primeiro a forma mais simples, que \u00e9 a partir da linha de comando: voc\u00ea usa a <strong>system property<\/strong> <em>spring.profiles.active<\/em>. Vamos a um exemplo:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">java -Dspring.profiles.active=prod AplicacaoLinda.jar<\/pre>\n\n\n\n<p>Definimos que nossa aplica\u00e7\u00e3o ir\u00e1 executar usando o profile <em>prod<\/em>. E se eu quiser usar mais de um profile ao mesmo tempo? E se eu quiser usar os profiles prod e relacional? Separe com v\u00edrgulas:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">java -Dspring.profiles.active=prod,relacional AplicacaoSuperPoderosa.jar<\/pre>\n\n\n\n<p>Mas h\u00e1 outras maneiras: voc\u00ea pode definir o profile por arquivos de configura\u00e7\u00e3o, Maven, em tempo de execu\u00e7\u00e3o e outros. Este <a href=\"https:\/\/www.baeldung.com\/spring-profiles\">link aqui<\/a> pode te ensinar estas outras maneiras.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/images.pexels.com\/photos\/2743739\/pexels-photo-2743739.jpeg?auto=compress&amp;cs=tinysrgb&amp;h=750&amp;w=1260\" alt=\"Aten\u00e7\u00e3o\" width=\"210\" height=\"140\"\/><\/figure><\/div>\n\n\n\n<p><strong>Se eu n\u00e3o selecionar um profile, que profile \u00e9 carregado?<\/strong> <strong> <\/strong>O profile <strong>default<\/strong>. Importante que voc\u00ea tenha esta informa\u00e7\u00e3o em mente. No Spring Boot n\u00e3o existem profiles como <em>dev, prod, test<\/em> por padr\u00e3o, mas como vemos em diversos posts, acabamos por achar que eles existem no framework.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Programaticamente <\/h5>\n\n\n\n<p>Antes da aplica\u00e7\u00e3o ser iniciada, no m\u00e9todo main, voc\u00ea pode usar o m\u00e9todo <em>setAdditionalProfiles<\/em> da classe <em>SpringApplication<\/em>. Importante voc\u00ea saber que ap\u00f3s a aplica\u00e7\u00e3o ter sido iniciada n\u00e3o \u00e9 mais poss\u00edvel trocar o perfil (at\u00e9 onde sei). Mais detalhes sobre os perfis do Spring Boot <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/1.2.0.M1\/reference\/html\/boot-features-profiles.html\">neste link<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Terceiro andar: Spring Boot e suas auto configura\u00e7\u00f5es<\/h2>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pbs.twimg.com\/profile_images\/1235868806079057921\/fTL08u_H_400x400.png\" alt=\"Spring Boot (@springboot) | Twitter\" width=\"152\" height=\"152\"\/><\/figure><\/div>\n\n\n\n<p>Calma, \u00e9 o \u00faltimo andar MESMO agora (por enquanto, pois n\u00e3o vou falar aqui do Spring Cloud). O Spring Boot adiciona <strong>mais uma abstra\u00e7\u00e3o importante referente a configura\u00e7\u00f5es: as auto configura\u00e7\u00f5es.<\/strong><\/p>\n\n\n\n<p>Muita gente ignora este aspecto do &#8220;Boot&#8221;: o framework \u00e9 composto por diversos m\u00f3dulos que voc\u00ea pode adicionar ao seu projeto, identificados no Maven\/Gradle com o nome &#8220;spring-boot-starter-*&#8221;, e cada um destes m\u00f3dulos cont\u00e9m, al\u00e9m das suas pr\u00f3prias funcionalidades, suas pr\u00f3prias configura\u00e7\u00f5es (auto configura\u00e7\u00f5es), ativadas no momento em que a aplica\u00e7\u00e3o \u00e9 iniciada.<\/p>\n\n\n\n<p><strong>\u00c9 fundamental que voc\u00ea saiba disto<\/strong> por que temos aqui aplicado o conceito de conven\u00e7\u00f5es sobre configura\u00e7\u00e3o. O autor do m\u00f3dulo define qual ser\u00e1 o seu comportamento padr\u00e3o e cabe a <strong>voc\u00ea customizar o que \u00e9 necess\u00e1rio para o seu projeto.<\/strong> Mas a\u00ed entra a seguinte quest\u00e3o: como saber quais s\u00e3o estas configura\u00e7\u00f5es? Simples: voc\u00ea executa sua aplica\u00e7\u00e3o com o par\u00e2metro &#8211;debug e todas ser\u00e3o impressas no console. Exemplo:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">java --debug -jar AplicacaoLinda.jar<\/pre>\n\n\n\n<p>E se eu estiver usando Maven ou Gradle no meu ambiente de desenvolvimento? D\u00e1 pra passar o par\u00e2metro tamb\u00e9m.<\/p>\n\n\n\n<p>Sendo assim se voc\u00ea usa, por exemplo, o m\u00f3dulo JPA do Spring Boot: <em>spring-boot-starter-jpa<\/em>, automaticamente \u00e9 configurado um datasource para voc\u00ea. E estas configura\u00e7\u00f5es variam de m\u00f3dulo para m\u00f3dulo, mas n\u00e3o fique triste. Mas como estas configura\u00e7\u00f5es s\u00e3o carregadas e onde est\u00e3o?<\/p>\n\n\n\n<p>No momento em que a aplica\u00e7\u00e3o \u00e9 iniciada o Spring varre todos os arquivos JAR presentes no seu classpath que perten\u00e7am a estes m\u00f3dulos. E em cada um destes busca por um arquivo chamado <em>spring.factories<\/em>, presente no diret\u00f3rio <em>META-INF<\/em> do JAR. Neste arquivo est\u00e3o listadas as classes de configura\u00e7\u00e3o (@Configuration) que s\u00e3o as respons\u00e1veis por configurar aquele m\u00f3dulo.<\/p>\n\n\n\n<p><strong>Dica<\/strong>: leia <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/2.4.0\/reference\/htmlsingle\/#boot-features-developing-auto-configuration\">este t\u00f3pico<\/a> da documenta\u00e7\u00e3o oficial do Spring Boot para entender como estes m\u00f3dulos s\u00e3o escritos.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Carregando configura\u00e7\u00f5es<\/h1>\n\n\n\n<figure class=\"wp-block-image alignwide\"><img decoding=\"async\" src=\"https:\/\/fee.org\/media\/33425\/screen-shot-2019-04-02-at-10951-pm.png?anchor=center&amp;mode=crop&amp;width=1200&amp;rnd=132017178740000000\" alt=\"Revolu\u00e7\u00e3o Industrial\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Agora que estamos no &#8220;\u00faltimo andar&#8221; \u00e9 muito importante que voc\u00ea tenha em mente o objetivo de que <strong>configura\u00e7\u00f5es devem ser externas ao seu c\u00f3digo fonte<\/strong>. Desde o seu lan\u00e7amento uma das principais features do Spring Boot foi o fato de ter <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/2.4.0\/reference\/htmlsingle\/#boot-features-external-config\">&#8220;configura\u00e7\u00f5es externaliz\u00e1veis&#8221;<\/a>. A ideia \u00e9 simples: h\u00e1 um \u00fanico pacote da sua aplica\u00e7\u00e3o que ser\u00e1 implantado em diversos ambientes, cada qual com o seu pr\u00f3prio conjunto de configura\u00e7\u00f5es.<\/p>\n\n\n\n<p>Um dos objetivos do Spring Boot \u00e9 que voc\u00ea tenha um conjunto de configura\u00e7\u00f5es padr\u00e3o para executar a sua aplica\u00e7\u00e3o, mas que possam ser alteradas de acordo com o ambiente no qual o projeto \u00e9 executado. Sendo assim voc\u00ea teria, por exemplo, configura\u00e7\u00f5es \u00fanicas para acesso a banco de dados no ambiente de produ\u00e7\u00e3o, teste, homologa\u00e7\u00e3o, desenvolvimento, etc.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ordem de carregamento<\/h2>\n\n\n\n<p>Na documenta\u00e7\u00e3o oficial do Spring Boot voc\u00ea encontra <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/2.4.0\/reference\/htmlsingle\/#boot-features-external-config\">este link<\/a> que descreve as 14 fontes usadas pelo Spring Boot na busca por configura\u00e7\u00f5es (properties). A ideia \u00e9 fornecer ao desenvolvedor (ou equipe de opera\u00e7\u00e3o) um mecanismo que permita sobrescrever de forma f\u00e1cil praticamente qualquer configura\u00e7\u00e3o usada pela sua aplica\u00e7\u00e3o.<\/p>\n\n\n\n<p>Voc\u00ea pode ver a lista das 14 fontes no link que mencionei acima, mas vou copi\u00e1-la para c\u00e1 pois a usaremos para entender o funcionamento:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Configura\u00e7\u00f5es padr\u00e3o do framework.<\/li><li>As configura\u00e7\u00f5es que voc\u00ea define com a anota\u00e7\u00e3o @PropertySource<\/li><li>Arquivos de configura\u00e7\u00e3o (o famigerado application.data)<\/li><li>RandomValuePropertySource &#8211; um recurso do Spring Boot que permite inserir valores rand\u00f4micos em propriedades.<\/li><li>Vari\u00e1veis de ambiente do sistema operacional<\/li><li>Propriedades do sistema (as System Properties)<\/li><li>Via JNDI buscando em java:comp\/env (t\u00e1 a\u00ed um recurso pouco usado do Java e que \u00e9 bem \u00fatil, viu?)<\/li><li>Init params do ServletContext (em aplica\u00e7\u00f5es web)<\/li><li>Par\u00e2metros do ServletConfig. <\/li><li>Propriedades definidas na vari\u00e1vel de ambiente SPRING_APPLICATION_JSON (merece um post a parte este recurso, n\u00e3o inclu\u00ed neste post por que quis me ater apenas aos recursos mais usados)<\/li><li>Par\u00e2metros de linha de comando<\/li><li>Atributos properties nos testes.<\/li><li>@TestPropertySource &#8211; voc\u00ea inclui esta anota\u00e7\u00e3o nos seus testes automatizados com Spring.<\/li><li>Arquivo de configura\u00e7\u00f5es globais do Devtools (novamente, merece um post a parte este recurso, mas n\u00e3o o inclu\u00ed neste post para que seja poss\u00edvel nos ater apenas aos usos mais comuns)<\/li><\/ol>\n\n\n\n<p><strong>Muita confus\u00e3o<\/strong> surge a partir desta ordem de carregamento, ent\u00e3o vamos a um exemplo. Imagine que temos o seguinte arquivo &#8220;application.properties&#8221; (falaremos mais sobre este arquivo e suas variantes adiante, contenha sua ansiedade) no seu projeto:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">nome=Kico<br>sobrenome=Lobo<\/pre>\n\n\n\n<p>Se sua aplica\u00e7\u00e3o for compilada e executada sem quaisquer informa\u00e7\u00e3o adicional (java -jar Aplicacao.jar) os valores definidos neste arquivo ser\u00e3o mantidos (item 3). Sempre o Spring Boot verifica todos os elementos da lista ao executar a aplica\u00e7\u00e3o, sendo assim vamos continuar no exemplo para que a coisa fique mais simples, pois h\u00e1 uma pegadinha envolvendo algo sobre o qual falei no in\u00edcio deste post.<\/p>\n\n\n\n<p>Se houver uma vari\u00e1vel de ambiente  chamada &#8220;nome&#8221; com o valor &#8220;Nanna&#8221;, teremos aqui o valor &#8220;Nanna&#8221; aplicado na configura\u00e7\u00e3o (item 5, posterior ao 3).<\/p>\n\n\n\n<p>Se for passada a propriedade de sistema nome via par\u00e2metro (&#8220;-Dnome=Juca&#8221;) para a aplica\u00e7\u00e3o, o valor ser\u00e1 &#8220;Juca&#8221; (item 6, posterior ao 5 e 3). Sendo assim voc\u00ea pode sobrescrever vari\u00e1veis de ambiente na execu\u00e7\u00e3o do seu projeto tamb\u00e9m.<\/p>\n\n\n\n<p>At\u00e9 chegarmos ao item 11: &#8220;par\u00e2metros de linha de comando&#8221;. Aqui o Spring Boot reconhece o valor de vari\u00e1veis da seguinte forma: &#8220;&#8211;nome=Jucolino&#8221;. Sendo assim, se defini a vari\u00e1vel nome no arquivo (item 3), tamb\u00e9m uma vari\u00e1vel de ambiente com mesmo nome (item 5), mesmo assim ainda fui l\u00e1 e coloquei uma propriedade de sistema (item 6), se eu incluir um &#8220;&#8211;nome=JucolinoBruto&#8221; por linha de comando, prevalece o item 11 (em teoria).<\/p>\n\n\n\n<p>Via de regra: as fontes de configura\u00e7\u00e3o que tenham ordem maior s\u00e3o as que ser\u00e3o carregadas pelo seu projeto durante a inicializa\u00e7\u00e3o.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Arquivos de configura\u00e7\u00e3o<\/h2>\n\n\n\n<p>Muito cuidado com o item 3 da lista acima: arquivos de configura\u00e7\u00e3o. Aqui reside boa parte dos problemas que vejo as pessoas enfrentarem em seu dia a dia. Isto por que estes arquivos se dividem em duas categorias:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>application.properties definido para o perfil padr\u00e3o<\/li><li>application-[perfil].properties para os arquivos que n\u00e3o s\u00e3o o perfil padr\u00e3o. Exemplo: arquivo application-dev.properties para o perfil &#8220;dev&#8221;, application-prod.properties para o perfil &#8220;prod&#8221;.<\/li><\/ul>\n\n\n\n<p>O Spring Boot, tal como descrito <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/2.4.0\/reference\/htmlsingle\/#boot-features-external-config\">em sua documenta\u00e7\u00e3o<\/a>, carrega estes arquivos na seguinte ordem:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Arquivo application.properties embarcado na aplica\u00e7\u00e3o (classpath) para o perfil padr\u00e3o.<\/li><li>Arquivo application-[perfil].properties para perfis espec\u00edficos (exemplo: application-dev.properties para o perfil dev) embarcados no projeto.<\/li><li>Arquivo application.properties <strong>externo<\/strong> ao seu projeto. <\/li><li>Arquivo application-[perfil].properties <strong>externo <\/strong>ao seu projeto.<\/li><\/ol>\n\n\n\n<p>Sendo assim, imagine que eu tenha o arquivo application.properties embarcado em meu projeto com o seguinte conte\u00fado:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">server.port=8080<\/pre>\n\n\n\n<p>Esta propriedade define a porta do servi\u00e7o que identificar\u00e1 minha aplica\u00e7\u00e3o. Se for ativado o perfil &#8220;dev&#8221; no projeto, e existir internamente um arquivo chamado &#8220;application-dev.properties&#8221;, e neste o valor da propriedade &#8220;server.port&#8221; for &#8220;9090&#8221;, o valor usado pela aplica\u00e7\u00e3o ser\u00e1 o &#8220;9090&#8221;.<\/p>\n\n\n\n<p>Mas e se eu ativar mais de um perfil na minha aplica\u00e7\u00e3o, digamos, &#8220;dev,qa&#8221;. Os arquivos nos quais a chave ser\u00e1 buscada no classpath ser\u00e1:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>application.properties<\/li><li>application-dev.properties<\/li><li>application-qa.properties  (observe: os arquivos de perfil s\u00e3o carregados na ordem em que s\u00e3o declarados pela propriedade spring.profiles.active)<\/li><\/ol>\n\n\n\n<p>Se no mesmo exemplo a propriedade &#8220;server.port&#8221; estiver definida tamb\u00e9m no arquivo &#8220;application-qa.properties&#8221; com valor &#8220;1234&#8221;, &#8220;1234&#8221; ser\u00e1 o valor da propriedade no final.<\/p>\n\n\n\n<p>O que nos leva \u00e0 pergunta: <strong>mas e nos casos em que o arquivo estiver externo? Aonde est\u00e1 este arquivo?<\/strong> A se\u00e7\u00e3o <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/2.4.0\/reference\/htmlsingle\/#boot-features-external-config\">4.2.3 da documenta\u00e7\u00e3o<\/a> oficial nos responde com as conven\u00e7\u00f5es aplicadas pelo framework.<\/p>\n\n\n\n<p>As configura\u00e7\u00f5es externas podem estar (e ser\u00e3o carregadas seguindo a mesma ordem):<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>No diret\u00f3rio corrente<\/li><li>Na pasta \/config do diret\u00f3rio corrente<\/li><li>Sub-diret\u00f3rios da pasta \/config<\/li><\/ol>\n\n\n\n<p>N\u00e3o gostou de nenhuma das op\u00e7\u00f5es acima? Ok, defina ent\u00e3o uma propriedade do spring chamada &#8220;spring.config.location&#8221;, cujo valor apontar\u00e1 para o diret\u00f3rio no qual os arquivos de configura\u00e7\u00e3o dever\u00e3o ser buscados e apenas ali eles ser\u00e3o buscados no caso da busca externa.<\/p>\n\n\n\n<p>Voc\u00ea deve ter em mente aqui o conceito de &#8220;heran\u00e7a&#8221;. Se for usar o arquivo &#8220;application.properties&#8221; embarcado em sua aplica\u00e7\u00e3o apenas aquilo que \u00e9 <strong>estritamente essencial<\/strong> para a execu\u00e7\u00e3o do seu c\u00f3digo deve estar ali presente. Este arquivo essencialmente deve ser <strong>m\u00ednimo<\/strong>. E a\u00ed as configura\u00e7\u00f5es relativas ao ambiente (Environment) no qual a aplica\u00e7\u00e3o ser\u00e1 executada voc\u00ea pode incluir no arquivo externo do ambiente padr\u00e3o (application.properties) ou por perfil espec\u00edfico (application-[perfil].properties) em um dos diret\u00f3rios que citei acima.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">E como eu uso estas propriedades no meu c\u00f3digo?<\/h2>\n\n\n\n<p>F\u00e1cil, f\u00e1cil, voc\u00ea usa a anota\u00e7\u00e3o @Value, tal como no exemplo a seguir:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Value(\"${nome}\") \/\/ aplicando a propriedade nome<br>private String nome;<\/pre>\n\n\n\n<p>Esta \u00e9 de longe a forma mais comum. Foge deste post entrar em detalhes de c\u00f3digo, mas voc\u00ea pode aprender bastante a respeito <a href=\"https:\/\/www.baeldung.com\/spring-value-annotation\">neste link<\/a>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Boas pr\u00e1ticas<\/h1>\n\n\n\n<figure class=\"wp-block-image alignwide\"><img decoding=\"async\" src=\"https:\/\/images.pexels.com\/photos\/417070\/pexels-photo-417070.jpeg?auto=compress&amp;cs=tinysrgb&amp;h=750&amp;w=1260\" alt=\"Foto profissional gr\u00e1tis de a\u00e7\u00e3o, acidente, amea\u00e7a\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>N\u00e3o gosto muito de falar em boas pr\u00e1ticas por que cada caso \u00e9 \u00fanico e muitas vezes quem usa o termo &#8220;boas pr\u00e1ticas&#8221; age de forma dogm\u00e1tica. Por\u00e9m em diversas consultorias que presto observo a ocorr\u00eancia de alguns erros que n\u00e3o s\u00f3 geram d\u00e9ficits t\u00e9cnicos como que tamb\u00e9m acabam por colocar em risco os stakeholders do projeto. Sendo assim segue uma pequena lista.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cuidado com informa\u00e7\u00f5es sens\u00edveis<\/h2>\n\n\n\n<p>Entenda por informa\u00e7\u00f5es sens\u00edveis aquelas que n\u00e3o podem vazar sob hip\u00f3tese alguma: informa\u00e7\u00f5es de acesso a banco de dados, credenciais a servi\u00e7os cloud, senhas, n\u00fameros de documento, API keys, etc.<\/p>\n\n\n\n<p>Estas informa\u00e7\u00f5es n\u00e3o devem estar <strong>jamais<\/strong> no c\u00f3digo fonte da aplica\u00e7\u00e3o ou no reposit\u00f3rio. No caso do Spring Boot, o ideal \u00e9 que elas estejam presentes portanto em arquivos de configura\u00e7\u00e3o externos, vari\u00e1veis de ambiente, par\u00e2metros de inicializa\u00e7\u00e3o, enfim: estas informa\u00e7\u00f5es devem estar apenas no ambiente que precisa delas para que sua aplica\u00e7\u00e3o funcione.<\/p>\n\n\n\n<p>\u00c9 muito comum, por exemplo, encontrar em pacotes uma s\u00e9rie de arquivos, tais como:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>application-prod.properties<\/li><li>application-qa.properties<\/li><\/ul>\n\n\n\n<p>Imagine se este pacote vaza e nestes arquivos est\u00e3o estas informa\u00e7\u00f5es sens\u00edveis. Evite ao m\u00e1ximo. Existem inclusive op\u00e7\u00f5es que permitem armazenar segredos (informa\u00e7\u00f5es sens\u00edveis) de forma segura pra voc\u00ea, como o <a href=\"https:\/\/www.vaultproject.io\/\">Vault<\/a>, por exemplo, que pode inclusive ser integrado ao Spring (especialmente Spring Cloud).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Arquivo de configura\u00e7\u00e3o m\u00ednimo<\/h2>\n\n\n\n<p>\u00c9 um repeteco de algo que falei acima: ap\u00f3s ter removido todas as informa\u00e7\u00f5es sens\u00edveis de sua configura\u00e7\u00e3o embarcada, minimize ao m\u00e1ximo o conte\u00fado do arquivo application.properties. O ideal \u00e9 que este contenha apenas o essencial para que sua aplica\u00e7\u00e3o possa ser executada no ambiente de desenvolvimento.<\/p>\n\n\n\n<p>Por que ambiente de desenvolvimento, Kico? S\u00f3 pra dar produtividade para os desenvolvedores. As demais configura\u00e7\u00f5es voc\u00ea sobrescreve nas diversas fontes que mencionei acima (as outras 11). O ideal \u00e9 que esteja externalizado tamb\u00e9m no ambiente de desenvolvimento as informa\u00e7\u00f5es sens\u00edveis para garantir a seguran\u00e7a dos dados.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Use e abuse das vari\u00e1veis de ambiente<\/h2>\n\n\n\n<p>O ideal na minha opini\u00e3o \u00e9 termos apenas um arquivo embarcado <em>application.properties<\/em> que obtenha todos os seus dados a partir de vari\u00e1veis de ambiente caso estas existam e use valores padr\u00e3o caso n\u00e3o existam. Como faz isto?<\/p>\n\n\n\n<p>Basta seguir a sintaxe do exemplo a seguir:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">server.port=${SERVER_PORT:8080}<\/pre>\n\n\n\n<p>Neste exemplo, se existir uma vari\u00e1vel de ambiente chamada SERVER_PORT, seu valor \u00e9 usado, caso contr\u00e1rio, \u00e9 usado o valor 8080. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cuidado com passagem de configura\u00e7\u00f5es pela linha de comando<\/h2>\n\n\n\n<p>\u00c9 muito comum em momentos de aperto iniciarmos o processo da nossa aplica\u00e7\u00e3o trocando os par\u00e2metros de inicializa\u00e7\u00e3o (itens 6 e 11 da ordem de inicializa\u00e7\u00e3o acima mencionada) e n\u00e3o documentarmos isto. Consequentemente, o processo ir\u00e1 ser terminado no futuro e voc\u00ea n\u00e3o sabe mais aqueles valores.<\/p>\n\n\n\n<p>Caso v\u00e1 realizar algo assim, garanta que exista um script de inicializa\u00e7\u00e3o do seu projeto e altere nele tamb\u00e9m estes valores ou, melhor ainda, inclua estas informa\u00e7\u00f5es nas vari\u00e1veis de ambiente.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Documenta estas configura\u00e7\u00f5es por miseric\u00f3rdia!<\/h2>\n\n\n\n<p>O que voc\u00ea lembra hoje vai esquecer amanh\u00e3. Especialmente no caso de existir uma equipe de opera\u00e7\u00f5es, tenha documentado aonde encontram-se as configura\u00e7\u00f5es do sistema. S\u00e3o vari\u00e1veis de ambiente? \u00d3timo! Quais?<\/p>\n\n\n\n<p>Caso contr\u00e1rio ser\u00e1 necess\u00e1rio abrir seu pacote pra descobrir estas vari\u00e1veis e isto ser\u00e1 muito, muito triste.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Concluindo<\/h1>\n\n\n\n<p>Bom, este post serviu pra mostrar os principais conceitos envolvendo configura\u00e7\u00f5es no Spring Boot. Muitas vezes vejo o pessoal as usando de modo intuitivo, baseado em tutoriais na Internet e sem entender por que est\u00e1 funcionando (ou n\u00e3o) aquele sistema. Ent\u00e3o \u00e9 importante saber estes detalhes.<\/p>\n\n\n\n<p>No caso do Spring Boot, que \u00e9 essencialmente a aplica\u00e7\u00e3o do conceito de conven\u00e7\u00e3o sobre configura\u00e7\u00e3o no Spring, isto se torna ainda mais importante pois h\u00e1 muitos detalhes que n\u00e3o s\u00e3o expostos de forma imediata \u00e0 equipe e que muitas vezes geram preju\u00edzos enormes de tempo, dinheiro e raz\u00e3o.<\/p>\n\n\n\n<p>Espero que lhes seja \u00fatil. Havendo algum erro no texto, por favor, entre em contato comigo nos coment\u00e1rios para que eu aplique as devidas corre\u00e7\u00f5es, ok? Usei como base essencialmente a \u00faltima vers\u00e3o do Spring Boot (2.4.0) como refer\u00eancia.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Voc\u00ea realmente sabe como funcionam as configura\u00e7\u00f5es no Spring Boot? Este post explica o essencial para que voc\u00ea n\u00e3o passe aperto!<\/p>\n","protected":false},"author":1,"featured_media":1922,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6,62,87,59],"tags":[84,106,107],"class_list":["post-3157","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","category-spring","category-spring-boot","category-spring-framework","tag-java","tag-spring","tag-spring-boot"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Entenda as configura\u00e7\u00f5es do Spring Boot! - \/dev\/Kico<\/title>\n<meta name=\"description\" content=\"Aprenda neste post como funcionam as configura\u00e7\u00f5es do Spring Boot e como evitar uma s\u00e9rie de problemas relacionados a estas!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/devkico.itexto.com.br\/?p=3157\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Entenda as Configura\u00e7\u00f5es do Spring Boot!\" \/>\n<meta property=\"og:description\" content=\"Aprenda neste post como funcionam as configura\u00e7\u00f5es do Spring Boot e como evitar uma s\u00e9rie de problemas relacionados a estas!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/devkico.itexto.com.br\/?p=3157\" \/>\n<meta property=\"og:site_name\" content=\"\/dev\/Kico\" \/>\n<meta property=\"article:published_time\" content=\"2020-11-29T21:34:01+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-11-29T21:34:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"300\" \/>\n\t<meta property=\"og:image:height\" content=\"300\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Kico (Henrique Lobo Weissmann)\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Entenda as configura\u00e7\u00f5es do Spring Boot!\" \/>\n<meta name=\"twitter:description\" content=\"Aprenda neste post como funcionam as configura\u00e7\u00f5es do Spring Boot e como evitar uma s\u00e9rie de problemas relacionados a estas!\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png\" \/>\n<meta name=\"twitter:creator\" content=\"@loboweissmann\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Kico (Henrique Lobo Weissmann)\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=3157\",\"url\":\"https:\/\/devkico.itexto.com.br\/?p=3157\",\"name\":\"Entenda as configura\u00e7\u00f5es do Spring Boot! - \/dev\/Kico\",\"isPartOf\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=3157#primaryimage\"},\"image\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=3157#primaryimage\"},\"thumbnailUrl\":\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png\",\"datePublished\":\"2020-11-29T21:34:01+00:00\",\"dateModified\":\"2020-11-29T21:34:03+00:00\",\"author\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7\"},\"description\":\"Aprenda neste post como funcionam as configura\u00e7\u00f5es do Spring Boot e como evitar uma s\u00e9rie de problemas relacionados a estas!\",\"breadcrumb\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=3157#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/devkico.itexto.com.br\/?p=3157\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=3157#primaryimage\",\"url\":\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png\",\"contentUrl\":\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png\",\"width\":300,\"height\":300,\"caption\":\"spring boot groovy spring cli microservi\u00e7os\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=3157#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/devkico.itexto.com.br\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Entenda as configura\u00e7\u00f5es do Spring Boot!\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#website\",\"url\":\"https:\/\/devkico.itexto.com.br\/\",\"name\":\"\/dev\/Kico\",\"description\":\"Desenvolvendo software\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/devkico.itexto.com.br\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7\",\"name\":\"Kico (Henrique Lobo Weissmann)\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g\",\"caption\":\"Kico (Henrique Lobo Weissmann)\"},\"sameAs\":[\"https:\/\/x.com\/loboweissmann\"],\"url\":\"https:\/\/devkico.itexto.com.br\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Entenda as configura\u00e7\u00f5es do Spring Boot! - \/dev\/Kico","description":"Aprenda neste post como funcionam as configura\u00e7\u00f5es do Spring Boot e como evitar uma s\u00e9rie de problemas relacionados a estas!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/devkico.itexto.com.br\/?p=3157","og_locale":"pt_BR","og_type":"article","og_title":"Entenda as Configura\u00e7\u00f5es do Spring Boot!","og_description":"Aprenda neste post como funcionam as configura\u00e7\u00f5es do Spring Boot e como evitar uma s\u00e9rie de problemas relacionados a estas!","og_url":"https:\/\/devkico.itexto.com.br\/?p=3157","og_site_name":"\/dev\/Kico","article_published_time":"2020-11-29T21:34:01+00:00","article_modified_time":"2020-11-29T21:34:03+00:00","og_image":[{"width":300,"height":300,"url":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png","type":"image\/png"}],"author":"Kico (Henrique Lobo Weissmann)","twitter_card":"summary_large_image","twitter_title":"Entenda as configura\u00e7\u00f5es do Spring Boot!","twitter_description":"Aprenda neste post como funcionam as configura\u00e7\u00f5es do Spring Boot e como evitar uma s\u00e9rie de problemas relacionados a estas!","twitter_image":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png","twitter_creator":"@loboweissmann","twitter_misc":{"Escrito por":"Kico (Henrique Lobo Weissmann)","Est. tempo de leitura":"19 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/devkico.itexto.com.br\/?p=3157","url":"https:\/\/devkico.itexto.com.br\/?p=3157","name":"Entenda as configura\u00e7\u00f5es do Spring Boot! - \/dev\/Kico","isPartOf":{"@id":"https:\/\/devkico.itexto.com.br\/#website"},"primaryImageOfPage":{"@id":"https:\/\/devkico.itexto.com.br\/?p=3157#primaryimage"},"image":{"@id":"https:\/\/devkico.itexto.com.br\/?p=3157#primaryimage"},"thumbnailUrl":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png","datePublished":"2020-11-29T21:34:01+00:00","dateModified":"2020-11-29T21:34:03+00:00","author":{"@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7"},"description":"Aprenda neste post como funcionam as configura\u00e7\u00f5es do Spring Boot e como evitar uma s\u00e9rie de problemas relacionados a estas!","breadcrumb":{"@id":"https:\/\/devkico.itexto.com.br\/?p=3157#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/devkico.itexto.com.br\/?p=3157"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/devkico.itexto.com.br\/?p=3157#primaryimage","url":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png","contentUrl":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png","width":300,"height":300,"caption":"spring boot groovy spring cli microservi\u00e7os"},{"@type":"BreadcrumbList","@id":"https:\/\/devkico.itexto.com.br\/?p=3157#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/devkico.itexto.com.br\/"},{"@type":"ListItem","position":2,"name":"Entenda as configura\u00e7\u00f5es do Spring Boot!"}]},{"@type":"WebSite","@id":"https:\/\/devkico.itexto.com.br\/#website","url":"https:\/\/devkico.itexto.com.br\/","name":"\/dev\/Kico","description":"Desenvolvendo software","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/devkico.itexto.com.br\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"pt-BR"},{"@type":"Person","@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7","name":"Kico (Henrique Lobo Weissmann)","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g","caption":"Kico (Henrique Lobo Weissmann)"},"sameAs":["https:\/\/x.com\/loboweissmann"],"url":"https:\/\/devkico.itexto.com.br\/?author=1"}]}},"jetpack_featured_media_url":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/08\/spring-boot-project-logo.png","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/3157"}],"collection":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3157"}],"version-history":[{"count":6,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/3157\/revisions"}],"predecessor-version":[{"id":3166,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/3157\/revisions\/3166"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/media\/1922"}],"wp:attachment":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3157"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3157"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3157"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}