PropertyPlaceholderConfigurer는 프로퍼티 파일의 속성을 가지고 ${database.name}과 같은 프로퍼티 값을 바꿔주는 매우 유용한 기능을 가지고 있어서 자주 사용된다. 스프링의 기초정도만 배웠어도 DataSource를 직접 스프링에서 정의하는 할 때 DB연결정보는 프로퍼티 파일로 빼고 ${database.url}과 같은 식으로 쓰라는 것은 한번쯤 들어봤을 것이다.

context 네임스페이스를 쓰면 더욱 정의하기 편하다. 다음과 같이 적어주면 내부적으로 PropertyPlaceholderConfigurer가 만들어지고 모든 ${}로 정의된 빈의 프로퍼티 값을 프로퍼티 파일의 바꿔치기 해준다.

 <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>

 

프로퍼티 값은 애노테이션을 쓴다면 @Value에 의해서 지정할 수 있다.

그렇다면 다음과 같은 코드도 만들어 볼 수 있지 않을까?

public class BeanSP {

    @Value("#{systemProperties['os.name']}")

    String name;

    @Value("${database.username}")

    String username;

    @Bean

    public PropertyPlaceholderConfigurer databaseProperty() {

        PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();

        ppc.setLocation(new ClassPathResource("database.properties", getClass()));

        return ppc;

    }

}

name은 SpEL을 사용해서 다이나믹하게 시스템 프로퍼티 값을 가져온 것이다. SpEL이 알아서 동작하니 신경쓸 건 없고.

두번째 username은 PropertyPlaceholderConfigurer에 의해서 변경되는 전형적인 ${}을 가지고 있으니 적절한 PropertyPlaceholderConfigurer와 프로퍼티 파일만 만들어주면 DB접속이름으로 변경될 것이라고 기대한다.

보통 PropertyPlaceholderConfigurer은 XML에 정의하지만 XML없는 컨텍스트를 사용하기 위해서 @Bean을 붙여 자바코드에 의한 빈 설정 기능을 사용했다. 이제 BeanSP만 빈으로 등록해주면 @Bean이 붙은 databaseProperty() 메소드에 의해서 PropertyPlaceholderConfigurer 타입의 빈이 등록될 것이고 그러면 당연히 username의 값도 변경될 것이라고 기대할 수 있다.

 

그러나 테스트 해보면 ${database.username}은 바뀌지 않는다. 파일도 잘 만들었을 뿐더러 확인해보면PropertyPlaceholderConfigurer 타입의 빈도 정상적으로 등록되어있다. XML로 바꿔서 등록하면 당연히 잘 된다.

그렇다면 @Bean을 사용해서 정의하면 왜 안될까?

 

이를 알려면 PropertyPlaceholderConfigurer @Bean애노테이션이 붙은 클래스를 스프링이 어떻게 처리하는지에 대한 두가지 지식이 모두 필요하다.

이 두가지 기능은 모두 BeanFactoryPostProcessor(BFPP)에 의해서 처리된다. BFPP는 빈 정의가 모두 준비되었을 때 진행하는 빈 팩토리 후처리기이다. 준비된 빈 정의 자체를 어떤 식으로든 바꿔치기 할 수 있기 때문에 상당히 유용하다.

PropertyPlaceholderConfigurer는 프로퍼티 파일의 속성과 빈 정의에 나온 프로퍼티 값을 비교해서 일치하면 프로퍼티 값 정의 자체를 바꿔주는 것이다. 그래서 ${database.name}이 user1과 같은 값 설정으로 바뀌고 나중에 빈을 만들면 이 빈 정의에 따라서 바뀐 값으로 만들어지는 것이다.

@Bean에 의해서 빈이 등록되는 것은 ConfigurationClassPostProcessor(CCPP) BFPP에 의해서 진행된다. 이 BFPP는 한 술 더 떠서 아예 새로운 빈 정의를 추가해준다. BFPP는 빈 정의를 어떤 식으로든 조작할 수 있는 강력한 기능을 가지도록 정의된 것으로 스프링은 이를 이용해서 많은 기능을 확장해왔다. 그래서 이 BFPP가 동작하는 동안에 @Bean이 붙은 빈 정의를 발견하면 그 내용을 토대로 새로운 빈 정의를 추가해준다.

자.. 문제는 BFPP가 실행되는 시점이다.  순서를 잘 보자.

1. 먼저 위의 BeanSP가 빈으로 등록된다. XML이든 스캐닝이든, 직접 주입이든 암튼 컨텍스트의 빈 설정으로 등록된다. 이 때 아직 @Bean에 의해서 CCPP가 만들어지지 않았다.

2. 이미 ConfigurationClassPostProcessor는 등록되어있다. AnnotationConfigApplicationContext라면 초기화 과정에서 추가해줄 것이고, XML이라면 <context:annotation-config>에 의해서 추가되어있을 것이다.

3. 기본 빈 등록이 끝났으므로 등록된 빈 중에서 BFPP를 찾는다. 지금까지 빈으로 등록된 BFPP는 ConfigurationClassPostProcessor뿐이다.

4. 모든 BFPP를 실행한다. 따라서 CCPP가 후처리기로 동작한다. 이 때 @Bean 메소드를 발견하고 PropertyPlaceholderConfigurer 타입의 빈을 등록해준다.

5. 끝.

문제는 3과 4의 순서이다. @Bean에 의해서 등록되는 빈은 이미 3번 과정에서 BFPP를 모두 찾아서 BFPP에 대한 실행이 시작된 이후에 일어난다. 따라서 4번 과정에서 등록된 PropertyPlaceholderConfigurer은 다시 3번으로 돌아가서 컨텍스트가 실행할 BFPP의 후보로 추가될 수 없다.

따라서 PropertyPlaceholderConfigurer는 빈으로 등록되지만 BFPP로 실행되는 시점이 지난 후기 때문에 무용지물이다.

 

결론은 "BFPP 빈은 다른 BFPP(CCPP)에서 등록되게 만들면 안된다".

XML을 사용하지 않으면서 위의 문제를 풀려면 다음과 같이 아예 독립적으로 PropertyPlaceholderConfigurer를 만들어 초기부터 빈으로 바로 등록되게 하면 된다.

@Component

public class DatabasePropertyPlaceHolder extends PropertyPlaceholderConfigurer {

    public DatabasePropertyPlaceHolder() {

        this.setLocation(new ClassPathResource("database.properties", getClass()));

    }

}

비슷한 원리가 BeanPostProcessor에도 적용될 수 있다. BPP에서 빈을 등록할 일은 없겠지만 기존 프로퍼티 내용을 조작하려고 하려면 BPP의 순서를 잘 염두에 둬야 한다.

또, BFPP가 단지 시간순서의 문제라면 BFPP빈의 실행순서를 조정하는 것은 가능하다. priority나 order를 지정하면 우선적으로 실행될 BFPP를 지정할 수 있다.

AC가 빈 등록이후 초기화 하는 작업의 순서를 알고 싶다면 AbstractApplicationContext의 refresh() 메소드를 참고하면 된다. 구체적인 후처리 작업에 대해서는 BFPP와 BPP를 beanFactory에서 가져와 출력해보면 된다. 스프링 초보자가 아니라면 적어도 자신이 만든 설정에 의해서 어떤 BF, Bean 후처리기들이 동작하는지쯤은 알아야 한다.

Related posts:

  1. Inside Spring (6) 애노테이션 설정 지원 스프링 웹 테스트용 DispatcherServlet 만들기
  2. Spring 3.0 (59) 프로퍼티 파일 이용하기 – placeholder vs SpEL
  3. Spring 3.0 (60) 클래스패스 리소스를 지정할 때 주의사항과 팁
  4. 스프링 3.1 (4) Static @Bean 메소드
  5. Spring 3.0 (14) Context Support 모듈의 선택 라이브러리 분석
  6. Spring 3.0 (26) Spring Expression Language와 @Value
  7. Spring 3.0 (33) JavaConfig의 통합과 변신. 메타-빈(meta-bean) 개념의 등장.
  8. Spring 3.0 (13) Context 모듈의 선택 라이브러리 분석
  9. Spring 3.0 (15) Jdbc 모듈의 선택 라이브러리 분석
  10. Spring 3.0 EL (Spel)을 이용한 AssertThrows 확장 (1)
  11. Spring 3.0 (56) @Bean 사용의 주의사항
  12. Spring 3.0 (58) Static Class를 XML없이 빈으로 등록하기
  13. Spring 3.0 (20) Transaction 모듈의 선택 라이브러리
  14. Spring 상식퀴즈 (1) – DI 태클하기
  15. Spring 3.0 (2) R-518 스프링의 새 모듈 OXM(Object/XML Mapping)

Facebook comments:

to “Inside Spring (5) PropertyPlaceholderConfigurer를 @Bean으로 정의해서는 안되는 이유”

  1. below you will come across the link to some web sites that we believe you must visit

  2. I am commenting to make you be aware of what a great encounter my child encountered studying your blog. She discovered too many things, which include what it’s like to possess a marvelous helping style to let other folks without problems completely grasp specific specialized topics. You really exceeded readers’ expectations. Thanks for rendering these valuable, trusted, edifying and even unique guidance on your topic to Lizeth.

  3. usually posts some quite intriguing stuff like this. If you are new to this site

  4. we prefer to honor lots of other web web pages around the internet, even if they arent linked to us, by linking to them. Beneath are some webpages worth checking out

  5. you’re in point of fact a good webmaster. The website loading velocity is amazing. It seems that you are doing any distinctive trick. Also, The contents are masterpiece. you’ve performed a excellent job in this topic!|

  6. below you will discover the link to some websites that we think it is best to visit

  7. You really make it appear really easy together with your presentation but I in finding this matter to be really one thing which I feel I might by no means understand. It sort of feels too complicated and extremely wide for me. I am taking a look ahead to your subsequent submit, I’ll attempt to get the hang of it!|

  8. It’s remarkable in favor of me to have a web site, which is valuablefor my know-how. thanks admin

  9. please pay a visit to the web pages we adhere to, including this one, because it represents our picks in the web

  10. I’ve been surfing online more than 2 hours today, yet I never found any interesting article like yours. It is pretty worth enough for me. In my view, if all website owners and bloggers made good content as you did, the internet will be much more useful than ever before.|

  11. that is the end of this write-up. Here youll discover some web pages that we feel you will enjoy, just click the hyperlinks over

  12. Поледние сериалы Новая серии Прямой Эфир

  13. Турецкие сериалы сериал серия Фильмы – смотреть онлайн бесплатно в хорошем качестве

  14. Русские сериалы сериал серия Смотреть фильмы онлайн бесплатно в хорошем качестве

  15. Поледние сериалы серия в HD. Новые видео смотреть в HD Сериалы

  16. Your website helps me. thank you.

  17. Great content, please stay updated, I will check it often.

  18. Русские сериалы сериал новая серия Новинки кино смотреть онлайн

  19. Поледние сериалы все серии Фильмы – смотреть онлайн бесплатно в хорошем качестве

  20. Hey There. I found your weblog the usage of msn. That is an extremely well written article. I’ll make sure to bookmark it and come back to learn more of your helpful info. Thank you for the post. I’ll definitely return.|

  21. Турецкие сериалы сезон новая серия Бесплатные фильмы и сериалы смотреть онлайн

  22. Русские сериалы все серии Онлайн кинотеатр

  23. It’s very easy to find out any matter on net as compared to books, as I found this piece of writing at this web page.|

  24. below you will obtain the link to some websites that we believe you must visit

  25. Турецкие сериалы серия русская озвучка Смотреть фильмы онлайн бесплатно в хорошем качестве

  26. we came across a cool web-site that you may well enjoy. Take a search if you want

  27. Турецкие сериалы все серии Смотреть Фильмы в HD онлайн. Список фильмов

  28. Hi there! canada drug great web page.

  29. Русские сериалы смотреть онлайн все серии подряд Смотреть Фильмы в HD онлайн. Список фильмов

  30. Here is a superb Weblog You may Discover Exciting that we Encourage You

  31. Турецкие сериалы сезон серия Онлайн кинотеатр

  32. Поледние сериалы серия в HD. Фильмы онлайн, смотреть бесплатно Кино онлайн

  33. here are some links to web sites that we link to since we consider they’re really worth visiting

  34. Поледние сериалы сезон серия Смотреть фильмы онлайн бесплатно в хорошем качестве

  35. Here is a great Blog You may Discover Intriguing that we Encourage You

  36. Турецкие сериалы сезон серия Прямой Эфир

  37. always a large fan of linking to bloggers that I enjoy but really don’t get a whole lot of link enjoy from

  38. This site was… how do I say it? Relevant!! Finally I’ve found something which helped me. Thanks a lot!|

  39. Русские сериалы сезон серия Новинки кино смотреть онлайн

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2017 Toby's Epril Suffusion theme by Sayontan Sinha