@Value는 인스턴스화 이후 처리된다.

김학준·2024년 6월 20일
0

게시판

목록 보기
44/44

문제 상황

파일을 저장하는 경로를 config.properties에서 불러오는데 이 값이 계속해서 null로 지정된다.

오류 메시지

없음

오류 발생 부분

.../resource-local/config.properties

file.save.path=/dev/attFile/
img.save.path=
img.access.host=

FileUtil.java

@Slf4j
@Component
public class FileUtil {
	@Value("#{config['file.save.path']}")
	private String BASE_SAVE_PATH;
    
    private String savePath;

	FileUtil() { 
		Calendar calendar = Calendar.getInstance(); 
		int year = calendar.get(Calendar.YEAR); 
		int month = calendar.get(Calendar.MONTH) + 1;
		int day = calendar.get(Calendar.DAY_OF_MONTH); 
		savePath += BASE_SAVE_PATH + "/" + year + "" + month + "" + day; 
	}

	public File saveFile(MultipartFile mf) throws IllegalStateException, IOException {
		File file = new File(SAVE_PATH);

해결 방법

이유

@Value 애너테이션은 BeanPostProcessor에 의해 처리되는데 이것이 어떻게 작동하는지를 살펴보자. 다음은 공식 문서의 일부이다.

Customizing Beans by Using a BeanPostProcessor

BeanPostProcessor instances operate on bean (or object) instances. That is, the Spring IoC container instantiates a bean instance and then BeanPostProcessor instances do their work.

Spring IoC 컨테이너는 Bean 인스턴스를 인스턴스화한 다음 BeanPostProcessor 인스턴스가 동작한다고 설명하고 있다.

정리하자면 다음과 같다.

  1. Bean 인스턴스 인스턴스화
  2. @Value로 값 불러오기 (BeanPostProcessor 인스턴스가 동작)

인스턴스화가 먼저 진행되기 때문에 BASE_SAVE_PATHnull인 상태에서 savePath 값이 null/[date]로 지정됐던 것이었다.

변경 후 코드

두 가지 방법이 있다.

  • 생성자의 파라미터에 @Value

FileUtil.java

@Slf4j
@Component
public class FileUtil { 
    private String savePath;

	FileUtil(@Value("#{config['file.save.path']}") String BASE_SAVE_PATH) { 
		Calendar calendar = Calendar.getInstance(); 
		int year = calendar.get(Calendar.YEAR); 
		int month = calendar.get(Calendar.MONTH) + 1;
		int day = calendar.get(Calendar.DAY_OF_MONTH); 
		savePath += BASE_SAVE_PATH + "/" + year + "" + month + "" + day; 
	}
  • @PostConstruct 사용
@Slf4j
@Component
public class FileUtil {
	@Value("#{config['file.save.path']}")
    private String savePath;
	
	@PostConstruct
	private void addDateToSavePath() { 
		Calendar calendar = Calendar.getInstance(); 
		int year = calendar.get(Calendar.YEAR); 
		int month = calendar.get(Calendar.MONTH) + 1;
		int day = calendar.get(Calendar.DAY_OF_MONTH); 
		savePath += "/" + year + "" + month + "" + day; 
	}

0개의 댓글