Spring Boot application.properties değeri doldurulmuyor


97

Bazı harici yapılandırmalarla çalışmaya çalıştığım çok basit bir Spring Boot uygulamam var. Yaylı önyükleme belgelerindeki bilgileri izlemeye çalıştım ancak bir yol engeli ile karşılaşıyorum.

Uygulamayı application.properties dosyasındaki harici konfigürasyonun altında çalıştırdığımda, bean içindeki değişkene yerleştirilmiyor. Eminim aptalca bir şey yapıyorum, herhangi bir öneriniz için teşekkürler.

MyBean.java (/ src / main / java / foo / bar / konumunda bulunur)

package foo.bar;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    @Value("${some.prop}")
    private String prop;

    public MyBean() {
        System.out.println("================== " + prop + "================== ");
    }
}

Application.java (/ src / main / java / foo / konumunda bulunur)

package foo;

import foo.bar.MyBean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

    @Autowired
    private MyBean myBean;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

application.properties (/ src / main / kaynaklar / dizininde bulunur)

some.prop=aabbcc

Spring Boot uygulamasını çalıştırırken günlük çıktısı :

grb-macbook-pro:properties-test-app grahamrb$ java -jar ./build/libs/properties-test-app-0.1.0.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.1.5.RELEASE)

2014-09-10 21:28:42.149  INFO 16554 --- [           main] foo.Application                          : Starting Application on grb-macbook-pro.local with PID 16554 (/Users/grahamrb/Dropbox/dev-projects/spring-apps/properties-test-app/build/libs/properties-test-app-0.1.0.jar started by grahamrb in /Users/grahamrb/Dropbox/dev-projects/spring-apps/properties-test-app)
2014-09-10 21:28:42.196  INFO 16554 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67e38ec8: startup date [Wed Sep 10 21:28:42 EST 2014]; root of context hierarchy
2014-09-10 21:28:42.828  INFO 16554 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2014-09-10 21:28:43.592  INFO 16554 --- [           main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
2014-09-10 21:28:43.784  INFO 16554 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2014-09-10 21:28:43.785  INFO 16554 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.54
2014-09-10 21:28:43.889  INFO 16554 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2014-09-10 21:28:43.889  INFO 16554 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1695 ms
2014-09-10 21:28:44.391  INFO 16554 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2014-09-10 21:28:44.393  INFO 16554 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
================== null==================
2014-09-10 21:28:44.606  INFO 16554 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-09-10 21:28:44.679  INFO 16554 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2014-09-10 21:28:44.679  INFO 16554 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2014-09-10 21:28:44.716  INFO 16554 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-09-10 21:28:44.716  INFO 16554 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-09-10 21:28:44.902  INFO 16554 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2014-09-10 21:28:44.963  INFO 16554 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
2014-09-10 21:28:44.965  INFO 16554 --- [           main] foo.Application                          : Started Application in 3.316 seconds (JVM running for 3.822)
^C2014-09-10 21:28:54.223  INFO 16554 --- [       Thread-2] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67e38ec8: startup date [Wed Sep 10 21:28:42 EST 2014]; root of context hierarchy
2014-09-10 21:28:54.225  INFO 16554 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

4
@ValueFasulye yapılmadan önce nasıl değiştirilmelidir? Değerin yanlış ayarlanmış olup olmadığını "algılama" şekliniz. O anda, @Valuenesne yapımından SONRA işleneceği için her zaman boş olacaktır.
M. Deinum

Yanıtlar:


165

Özelliğin enjeksiyonunu gerçekleştirme şekliniz çalışmayacaktır çünkü enjeksiyon, kurucu çağrıldıktan sonra yapılır.

Aşağıdakilerden birini yapmanız gerekir:

Daha iyi çözüm

@Component
public class MyBean {

    private final String prop;

    @Autowired
    public MyBean(@Value("${some.prop}") String prop) {
        this.prop = prop;
        System.out.println("================== " + prop + "================== ");
    }
}

Çalışacak ancak daha az test edilebilir ve biraz daha az okunabilir olan çözüm

@Component
public class MyBean {

    @Value("${some.prop}")
    private String prop;

    public MyBean() {

    }

    @PostConstruct
    public void init() {
        System.out.println("================== " + prop + "================== ");
    }
}

Ayrıca bunun Spring Boot'a özgü olmadığını, ancak tüm Spring uygulamaları için geçerli olduğunu unutmayın.


Çalışması için kurucuya bir @Autowired ek açıklaması eklemem gerekiyordu
Sébastien Tromp

1
Bahşiş için teşekkürler. Bu, @Değer ek açıklamasından bahsettiği Bahar belgelerinde olmalı - ancak bu adamlar belgeleriyle ilgili geri bildirimle ilgilenmiyor gibi görünüyor :(
Alex Worden

1
Beni biraz hayal kırıklığına uğrattı. Teşekkürler!
Robert Moskal

1
@geoand Ya 10'dan fazla değeriniz varsa, 10'unu da aynen yaptığınız gibi yazmanız gerekir mi? Yoksa daha temiz bir yol mu var
Jesse

1
@Jackie Gerçekten de daha temiz bir yol var! @ConfigurationProperties@EnableConfigurationProperties
Göz

5

"Geoand" kullanıcısı buradaki nedenleri göstermekte ve bir çözüm önermekte haklıdır. Ancak daha iyi bir yaklaşım, yapılandırmanızı ayrı bir sınıfa, örneğin SystemContiguration java sınıfına kapsüllemek ve ardından bu sınıfı, bu alanları kullanmak istediğiniz her hizmete enjekte etmektir.

Yapılandırma değerlerini doğrudan hizmetlere okuma şekliniz (@grahamrb) hataya açıktır ve yapılandırma ayarı adı değiştirilirse yeniden düzenleme baş ağrısına neden olur.


Bu mülk için ayrı bir sınıfınız olsaydı nasıl daha az baş ağrısı olmazdı? Yeniden düzenleme yaparken hala hatırlanması gereken bir dizeye sahip olacaksınız
dot_Sp0T

4
N sayısı değil, "hatırlamanız" gereken tek bir yer var. SystemContiguration'da bulunan skaler değerler size güçlü yazım sağlar. Ayrıca, konfigürasyondan gelen değerlere göre ~~~ "çatallara" sahip bir iş mantığı varsa ~~~ ..... değerlere ihtiyaç duyan sınıf / işletme mantığına bir şey enjekte etmek daha iyidir. Aka, SystemContiguration ile alay etmek ve ardından @Value'u her yerde çalıştırmaya çalışmak çok daha kolaydır.
granadaCoder

3

Aslında, aşağıda benim için iyi çalışıyor.

@Component
public class MyBean {

   public static String prop;

   @Value("${some.prop}")
   public void setProp(String prop) {
      this.prop= prop;
   }

   public MyBean() {

   }

   @PostConstruct
   public void init() {
      System.out.println("================== " + prop + "================== ");
   }

}

Şimdi nerede istersem, sadece çağır

MyBean.prop

değer döndürür.


2

Bu cevap sizin durumunuz için geçerli olabilir veya olmayabilir ... Benzer bir belirti yaşadığımda ve kodumu birçok kez iki kez kontrol ettim ve hepsi iyi görünüyordu, ancak @Valueayar hala geçerli değildi. Sonra yaptıktan sonra File > Invalidate Cache / Restartbenim ile IntelliJ(benim IDE), sorun ortadan kalktı ...

Bunu denemek çok kolay, bu yüzden denemeye değer olabilir


1

Environment sınıfını kullanarak uygulama alabiliriz. Özellikler değerleri

@Autowired,

private Environment env;

ve kullanarak erişim

String password =env.getProperty(your property key);

0

bu adımları takip et. 1: - aşağıda görebileceğiniz gibi konfigürasyon sınıfınızı oluşturun

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.beans.factory.annotation.Value;

@Configuration
public class YourConfiguration{

    // passing the key which you set in application.properties
    @Value("${some.pro}")
    private String somePro;

   // getting the value from that key which you set in application.properties
    @Bean
    public String getsomePro() {
        return somePro;
    }
}

2: - bir konfigürasyon sınıfınız olduğunda, ihtiyacınız olan bir konfigürasyondan değişkeni enjekte edin.

@Component
public class YourService {

    @Autowired
    private String getsomePro;

    // now you have a value in getsomePro variable automatically.
}

0

Birkaç farklı dosyayla büyük bir çok modüllü projede application.propertiesçalışıyorsanız, değerinizi ana projenin özellik dosyasına eklemeyi deneyin .

Hangisinin ana projeniz olduğundan emin değilseniz pom.xml, bir <parent>etiket için projenizin dosyasını kontrol edin .

Bu benim için sorunu çözdü.


0

EnvironmentVerileri almak için Class'ı kullanabilirsiniz :

@Autowired
private Environment env;
String prop= env.getProperty('some.prop');
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.