Spring Boot application.properties 값이 채워지지 않음


97

외부 구성으로 작업하려는 매우 간단한 Spring Boot 앱이 있습니다. 나는 스프링 부트 문서 의 정보를 따르려고 노력했지만 로드 블록에 부딪 혔습니다.

application.properties 파일의 외부 구성 아래에서 앱을 실행할 때 빈 내의 변수에 채워지지 않습니다. 어떤 제안을 해주셔서 감사합니다.

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 / main / resources /에 있음)

some.prop=aabbcc

Spring Boot 앱을 실행할 때의 로그 출력 :

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객체 생성 후 처리 되므로 항상 null 입니다.
M. Deinum 2014 년

답변:


165

생성자가 호출 된 후에 주입이 수행되기 때문에 속성 주입을 수행하는 방식은 작동하지 않습니다.

다음 중 하나를 수행해야합니다.

더 나은 솔루션

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

또한 Spring Boot와 관련이 없지만 모든 Spring 애플리케이션에 적용됩니다.


나는 그것을 작동하도록 생성자에 @Autowired 주석을 추가했다
세바스티앙 트롬 프

1
팁 고마워. 이것은 @Value 주석에 대해 이야기하는 Spring 문서에 있어야합니다. 그러나 그 사람들은 문서에 대한 피드백에 관심이없는 것 같습니다. (
Alex Worden

1
좌절감을 덜어주었습니다. 감사!
Robert Moskal 2016 년

1
@geoand 10 개 이상의 값이있는 경우 10 개를 모두 입력 한 방식대로 입력해야합니까? 아니면 더 깨끗한 방법이
Jesse

1
@Jackie 실제로 더 깨끗한 방법이 있습니다! 확인 @ConfigurationProperties@EnableConfigurationProperties주석
geoand

5

사용자 "geoand"는 여기서 그 이유를 지적하고 해결책을 제시하는 것이 옳습니다. 그러나 더 나은 접근 방식은 구성을 별도의 클래스 (예 : SystemContiguration Java 클래스)로 캡슐화 한 다음 해당 필드를 사용하려는 서비스에이 클래스를 삽입하는 것입니다.

구성 값을 서비스로 직접 읽는 현재 방법 (@grahamrb)은 오류가 발생하기 쉬우 며 구성 설정 이름이 변경되면 리팩토링 문제가 발생할 수 있습니다.


그 부동산에 대해 별도의 수업이 있다면 어떻게 덜 두통이 없을까요? 리팩토링 할 때 기억해야 할 문자열이 여전히 남아 있습니다
dot_Sp0T

4
"기억"해야 할 곳은 N 번호가 아니라 한 곳뿐입니다. SystemContiguration에 존재하는 스칼라 값은 강력한 유형을 제공합니다. 또한 구성에서 오는 값을 기반으로 ~~~~~~~~~~~~ ..... 값을 필요로하는 클래스 / businessLogic에 무언가를 삽입하는 것이 좋습니다. 일명 SystemContiguration을 조롱 한 다음 @Value가 모든 곳에서 작동하도록하는 것이 훨씬 쉽습니다.
granadaCoder

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 / RestartIntelliJ(내 IDE)를 사용한 후 문제가 사라졌습니다 ...

이것은 시도하기 매우 쉽기 때문에 한 번의 가치가있을 수 있습니다


1

환경 클래스를 사용하여 응용 프로그램을 얻을 수 있습니다. 속성 값

@Autowired,

private Environment env;

및 사용하여 액세스

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

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

EnvironmentClass를 사용 하여 데이터를 가져올 수 있습니다.

@Autowired
private Environment env;
String prop= env.getProperty('some.prop');
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.