स्प्रिंग बूट application.properties मान पॉपुलेटिंग नहीं है


96

मेरे पास एक बहुत ही सरल स्प्रिंग बूट ऐप है जिसे मैं कुछ बाहरी कॉन्फ़िगरेशन के साथ काम करने की कोशिश कर रहा हूं। मैंने स्प्रिंग बूट प्रलेखन पर जानकारी का पालन करने की कोशिश की है, हालांकि मैं एक सड़क ब्लॉक मार रहा हूं।

जब मैं एप्लिकेशन में बाहरी कॉन्फ़िगरेशन के नीचे एप्लिकेशन चलाता हूं। फ़ाइल में फ़ाइल बीन के भीतर चर में पॉपुलेट नहीं होती है। मुझे यकीन है कि मैं कुछ बेवकूफ कर रहा हूं, किसी भी सुझाव के लिए धन्यवाद।

MyBean.java (/ src / main / java / foo / bar / में स्थित)

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 /)

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 / मुख्य / संसाधन / में स्थित)

some.prop=aabbcc

स्प्रिंग बूट ऐप निष्पादित करते समय आउटपुट लॉग करें :

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
और @Valueसेम के निर्माण से पहले कैसे प्रतिस्थापित किया जाना चाहिए ? यदि मूल्य निर्धारित किया जाता है तो आपका "पता लगाने" का तरीका गलत है। उस समय यह हमेशा अशक्त @Valueरहेगा क्योंकि इसमें वस्तु निर्माण के बाद कार्रवाई की जाएगी।
एम। दीनुम

जवाबों:


163

जिस तरह से आप संपत्ति के इंजेक्शन का प्रदर्शन कर रहे हैं वह काम नहीं करेगा, क्योंकि निर्माणकर्ता को बुलाया जाने के बाद इंजेक्शन किया जाता है।

आपको निम्न में से एक करने की आवश्यकता है:

बेहतर समाधान

@Component
public class MyBean {

    private final String prop;

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

समाधान जो काम करेगा लेकिन कम परीक्षण योग्य है और थोड़ा कम पठनीय है

@Component
public class MyBean {

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

    public MyBean() {

    }

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

यह भी ध्यान दें कि स्प्रिंग बूट विशिष्ट नहीं है, लेकिन किसी भी स्प्रिंग एप्लिकेशन पर लागू होता है


मुझे इसे बनाने के लिए कंस्ट्रक्टर को @Autowired एनोटेशन जोड़ना पड़ा
Sébastien Tromp

1
पारितोषिक के लिए धन्यवाद। यह स्प्रिंग डॉक्यूमेंटेशन में होना चाहिए जहां यह @Value एनोटेशन के बारे में बात करता है - लेकिन उन लोगों को उनके डॉक्यूमेंटेशन पर फीडबैक में कोई दिलचस्पी नहीं दिखती है :(
एलेक्स वर्डेन

1
मुझे कुछ कुंठा बचाया। धन्यवाद!
रॉबर्ट मोस्कल

1
@geoand क्या होगा यदि आपके पास 10 से अधिक मूल्य हैं, तो क्या आपको सभी 10 को टाइप करना होगा जिस तरह से आपने किया था? या वहाँ एक क्लीनर तरीका है
जेसी

1
@ जैकी वास्तव में एक क्लीनर तरीका है! चेक आउट @ConfigurationPropertiesऔर @EnableConfigurationPropertiesएनोटेशन
जियोएंड

5

उपयोगकर्ता "जियोएंड" यहां कारणों को इंगित करने और समाधान देने में सही है। लेकिन एक बेहतर तरीका यह है कि अपने कॉन्फ़िगरेशन को एक अलग वर्ग में एन्क्रिप्ट करें, SystemContiguration जावा क्लास और फिर इस वर्ग को उन सेवाओं में इंजेक्ट करें जिन्हें आप उन क्षेत्रों का उपयोग करना चाहते हैं।

आपके वर्तमान तरीके (@grahamrb) को कॉन्फ़िगरेशन मानों को सीधे सेवाओं में पढ़ने में त्रुटि होती है और यदि कॉन्फ़िगरेशन नाम परिवर्तित किया जाता है तो रिफैक्टरिंग सिरदर्द हो सकते हैं।


यदि आपके पास उस संपत्ति के लिए एक अलग वर्ग होता तो कोई कम सिरदर्द नहीं होता? आपके पास अभी भी एक स्ट्रिंग होगी जिसे याद रखने की आवश्यकता होती है जब
dot_Sp0T

4
केवल एक जगह है जिसे आपको "याद रखना" चाहिए, एन नंबर नहीं। SystemContiguration पर मौजूद स्केलर मान आपको मजबूत टाइपिंग देता है। इसके अलावा, अगर व्यापार तर्क है जिसमें "कांटे" ~~~ है जो कॉन्फ़िगरेशन से आने वाले मूल्यों के आधार पर है ~~~ ..... यह बेहतर है कि वर्ग / व्यवसायिक में कुछ इंजेक्ट किया जाए जो मूल्यों की आवश्यकता है। अका, यह बहुत आसान है कि SystemContiguration का मज़ाक उड़ाया जाए और पूरी जगह @Value काम करने की कोशिश की जाए।
ग्रेनाकोडर

3

दरअसल, मेरे लिए नीचे ठीक काम करता है।

@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 + "================== ");
   }

}

अब मैं जहां भी चाहता हूं, बस आह्वान करता हूं

MyBean.prop

यह मान लौटाएगा।


2

यह उत्तर आपके मामले पर लागू हो सकता है या नहीं भी हो सकता है ... एक बार जब मैं एक समान लक्षण था और मैंने कई बार अपने कोड की जांच की और सभी अच्छे दिखे लेकिन @Valueसेटिंग अभी भी प्रभावी नहीं हो रही थी। और फिर File > Invalidate Cache / Restartमेरे IntelliJ(मेरे आईडीई) के साथ करने के बाद , समस्या दूर हो गई ...

यह कोशिश करना बहुत आसान है इसलिए एक शॉट के लायक हो सकता है



0

इन कदमों का अनुसरण करें। 1: - अपनी कॉन्फ़िगरेशन क्लास बनाएं जैसे आप देख सकते हैं

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: - जब आपके पास एक विन्यास वर्ग है तो चर में एक विन्यास से इंजेक्ट करें जहाँ आपको ज़रूरत है।

@Component
public class YourService {

    @Autowired
    private String getsomePro;

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

0

यदि आप कई अलग-अलग application.propertiesफ़ाइलों के साथ एक बड़े मल्टी-मॉड्यूल प्रोजेक्ट में काम कर रहे हैं , तो मूल प्रोजेक्ट की प्रॉपर्टी फ़ाइल में अपना मान जोड़ने का प्रयास करें ।

यदि आप अनिश्चित हैं जो आपकी मूल परियोजना है, तो टैग के pom.xmlलिए अपनी परियोजना की फ़ाइल देखें <parent>

इससे मेरे लिए समस्या हल हो गई।


0

Environmentडेटा प्राप्त करने के लिए आप क्लास का उपयोग कर सकते हैं :

@Autowired
private Environment env;
String prop= env.getProperty('some.prop');
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.