Spring boot 를 학습하던 도중
AWS에 올리려다 git에 노출되면 안되는 값이 있어 외부 yml 파일을 만들고
application.yml 파일에 include 해서 data를 사용하려 했다.
그런데 데이터 주입이 되지 않았다.
myval:
value: hi
이렇게 yml 파일이 설정 되어 있다고 가정 한다.
1. static 변수에 주입해서 사용했다
@Value("${myval.value}")
private static String val;
이런 식으로 사용 하였는데 데이터가 주입되지 않았다.
기존에 구현했던 클래스는 상수에 값을 때려 박고 그 값을 static 메소드에서 사용하도록 했었다.
그 점을 인지 못하고 그냥 변수 부분만 바꾸면 되겠지 하고 사용했지만, 실패!
2. static 키워드를 제거하고 new MyClass();와 같이 인스턴스 생성해서 사용했다.
@Component
@ConfigurationProperties(prefix="myval")
@Getter
@Setter
public class MyClass{
private String value;
}
new MyClass(); 로 생성해서 value값을 출력하는 메소드를 만들고 호출해 봤지만
null 값이 나온다. 실패!
3. (2)번 처럼 만든 클래스를 @Autowired로 주입 시켜 사용했다.
public class TestMain{
@Autowired
private MyClass myclass;
public void test(){
myclass.출력메소드();
}
}
yml 파일의 데이터를 사용하는 클래스를 호출하는 곳에서 출력 메소드를 호출해 봤고 성공했다!
@Autowired, @Inject, @Resource, @Value 어노테이션들은 스프링의 BeanPostProcessor 구현체가 처리한다. 이는 (무엇이든간에) 자신만의 BeanPostProcessor나 BeanFactoryPostProcessor 타입내에서는 이러한 어노테이션들을 적용할 수 없다는 의미이다. 이러한 타입들은 반드시 명시적으로 XML이나 스프링의 @Bean 메서드를 사용해서 '연결해야' 한다.
구글링을 해서 찾아봤지만 위와같은 글만 있고 정확한 원인은 찾을 수 없었다..
혹시 왜 그런지 알고 계시면 답변 부탁드립니다~~!
그리고 yml 또는 properties 파일에서 값을 읽어오는 Class에는 setter 메소드가 꼭 있어야 한다.!!!!!!
--------------------------------------추가--------------------------------
좀 더 알아본 결과 Property 값 주입은 Bean 컨테이너 즉 ApplicationConetxt가 하는데, 서버가 올라가고 ServletContext가 Initialize 되면 onRefresh 메서드에 의해 Bean이 초기화 된다. 이 때 Bean을 스캐닝해서 의존이 있다면 의존을 주입한다. 이 과정에서 플레이스 홀더에 값을 채워주는 것이다!..
그렇기 때문에 임의로 new를 이용해 인스턴스를 생성하게 되면 값 주입이 이루어 지지 않는 것이다.
중요한 것은 @Autowired가 아니라 플레이스 홀더가 있는 클래스가 Bean이면서 동시에 context refresh에 의해 처리 되는가 아닌가의 차이이다.
자세한 것은 Spring.io에 Properties 관련 항목을 보면 나와있다.
'Spring Framework > 에러' 카테고리의 다른 글
Spring porm.xml 첫줄 에러 (2) | 2019.11.05 |
---|---|
[Spring JPA] No serializer found for class org.hibernate 에러 (0) | 2019.07.24 |
[Spring JunitTest Hibernate error] org.hibernate.exception.ConstraintViolationException: could not execute statement (0) | 2019.07.24 |
[Spring JPA insertable, updatable] (1) | 2019.07.23 |
[Spring boot + JPA Hibernate 오류] error executing ddl via jdbc statement (0) | 2019.07.22 |