스터디/[토비의 스프링 3.1 Vol 1] (2025.03)

[토비의 스프링 3.1 Vol 2] 1장. 오브젝트와 의존관계(~1장)

ttoance 2025. 7. 6. 08:30
반응형

1.5.3 웹 애플리케이션의 새로운 IoC 컨테이너 구성 

  • 웹환경에서는 보통 루트 애플리케이션 컨텍스트와 서블릿 컨텍스트의 두 단계로 분리하는 경우가 일반적이다. 
  • 루트 컨텍스트와 서블릿 컨텍스트는 각각 web.xml의 <listener>와 <servlet>에 컨텍스트 설정 관련 정보를 넣어 웹 애플리케이션이 시작될 때 자동으로 생성되게 만든다. 

 

루트 애플리케이션 컨텍스트 등록 

  • <listener> 등록해주면 디폴트 컨텍스트 클래스인 XmlWebApplicationContext 이용해 애플리케이션 컨텍스트 만들고 /WEB-INF/applicationContext.xml을 설정파일로 사용한다. 

  • applicationContext.xml 파일 대신 @Configuration이 붙은 AppConfig 클래스를 빈 설정 메타정보로 해서 루트 애플리케이션 컨텍스트르 생성할 수 있다. 

 

서블릿 컨텍스트 등록 

  • 서블릿 컨텍스트는 DIspatcherServlet 서블릿을 등록하면 만들어진다 
  • 루트 애플리케이션 컨텍스트와 동일하게 XmlWebApplicationContext가 디폴트 컨텍스트 클래스다. 

 

 

1.5.4 런타임 환경 추상화와 프로파일 

환경에 따른 빈 설정정보 변경 전략과 한계 

  • 스프링으로 만든 애플리케이션은 성격이 다른 여러 환경에서 동작하게 된다. 
    • 보통 개발환경, 테스트환경, 운영환경 정도로 구분할 수 있다. 
  • 이렇게 애플리케이션이 실행되는 환경이 달라지면 일부 빈은 환경에 맞게 설정 메타 정보를 다르게 구성해야 한다. 

 

1) 빈 설정파일의 변경 

  • 가장 손쉽게 생각하는 방법은 메타정보 담은 XML이나 클래스 따로 준비해 각 환경마다 설정파일을 사용하게 만드는 것이다. 
  • (단점) 개발이나 유지보수가 진행되면서 설정정보가 지속적으로 달라지는 경우라면 이렇게 조금씩 내용이 다른 여러 벌의 설정 메타정보를 관리하는 것은 번거롭고 위험하다. 

 

2) 프로퍼티 파일 활용 

  • 빈 설정정보 담은 파일 통째로 여러 벌 가져가는 대신 환경에 따라 달라지는 정보 담은 프로퍼티 파일을 활용하는 방법도 있다. 
  • 빈 설정 메타정보 담은 XML이나 @Configuration 클래스는 애플리케이션 로직이 바뀌지 않는 한 건드리지 않고 환경에 따라 달라지는 외부 정보만 프로퍼티 파일 등에 두고 XML에서 읽어서 사용하는 방법이다. 
  • (장점) 애플리케이션을 구성하는 빈의 설정정보를 환경에 독립적으로 작성해서 환경이 바뀌어도 XML파일은 수정할 필요가 없다. 
    • 대신 각 환경에 따라 달라지는 정보만 프로퍼티 파일 등으로 준비하면 된다. 
  • (단점) 환경에 따라 아예 빈 클래스가 바뀌거나 빈 구성이 달라지는 경우가 있다. 
    • 개발 환경에서는 <jdbc:embedded-database>는 내장형 DB를 셋업하면서 자신은 DataSource타입 빈으로 등록 하고 
    • 운영 환경에서는 WAS가 제공하는 커넥션 풀을 사용하는 경우가 많으니 <jee:jndi-lookup> 전용 태그를 사용하기도 한다. 

 

3) 런타임 환경과 프로파일 

  • 런타임 환경은 애플리케이션 컨텍스트에 새롭게 도입된 개념이다. 
  • 컨텍스트 내부에 Environment 인터페이스를 구현한 런타임 환경 오브젝트가 만들어져서 빈을 생성하거나 의존관계를 주입할 때 사용한다. 
  • 런타임 환경은 프로파일 profile 과 프로퍼티 소스 property source 로 구성한다. 
    • 환경에 따라 프로파일과 프로퍼티 소스가 다르게 설정된 Environment 오브젝트가 사용되는 것이다. 

  • <beans> profile 값이 각각 spring-test, dev, production으로 나오는데 각각 테스트환경, 개발환경, 운영환경에서 사용되는 빈이라는 의미로 지정한 프로파일 이름이다. 
    • 개발자가 수동 테스트 위해 WAS에 올리는 경우라면 프로파일을 dev로 하고 애플리케이션을 실행한다. 
    • 내장형 DB 이용해 스프링 테스트 실행할 경우에는 spring-test로 지정해 애플리케이션을 실행한다. 

 

활성 프로파일 지정 방법 

  • 특정 프로파일에 정의된 빈을 사용하고 싶으면 해당 프로파일을 활성 프로파일로 만들어주면 된다. 
  • 프로파일 관련 정보는 Environment 타입의 오브젝트가 가지고 있다. 
  • 활성 프로파일을 시스템 프로퍼티나 환경변수를 통해 지정할 수 있다. 
    • 활성 프로파일을 지정할 시스템 프로퍼티 이름은 spring.profiles.active이다. 

 

 

1.5.5 프로퍼티 소스 

프로퍼티

  • 자바에서 말하는 프로퍼티는 기본적으로 키와 그에 대응되는 값의 쌍을 말한다. 
  • 프로퍼티 정보는 코드에서 직접 만드는 경우 제외하면 대부분 파일과 같은 외부 리소스에 키와 값의 형태로 저장되어 있다. 

 

스프링에서 사용되는 프로퍼티의 종류

 

1) 환경변수 

  • 스프링 애플리케이션이 구동되는 OS의 환경변수도 키와 값으로 표현되는 대표적인 프로퍼티다.
  • 자바에서는 System.getEnv() 메소드로 환경변수 담은 프로퍼티 맵을 가져올 수 있다. 
  • 환경변수 프로퍼티는 같은 시스템에서 여러 개의 WAS를 구동하더라도 모두 동일하게 적용되는 매우 넓은 범위에 적용되는 프로퍼티다. 
  • 시스템 관리자가 서버나 OS 레벨에 동일한 값 가진 프로퍼티 넣어 그 위에서 동작하는 모든 WAS의 모든 애플리케이션에 전달해야 한다면 사용을 고려해볼 만 한다. 

 

2) 시스템 프로퍼티

  • JVM 레벨에 정의된 프로퍼티를 말한다. 
  • JVM이 시작될 때 시스템 관련 정보 (os, name, user home) 부터 자바 관련 정보 (java.home, java.version, java.class 등)이 시스템 프로퍼티로 등록된다. 
  • -D로 지정한 커맨드라인 옵션도 포함된다. 
  • 시스템 프로퍼티는 코드에서 System.getProperties()로 가져올 수 있으며 타입은 Properties다.
  • 환경변수와 마찬가지로, 스프링이 자동으로 등록해주는 systemProperties 빈을 통해 접근할 수 있다. 

 

3) JNDI 

  • WAS 전체에 적용돼야 할 프로퍼티라면 시스템 프로퍼티가 좋겠지만, WAS에 여러 개의 웹 애플리케이션이 올라가고 그중 하나의 애플리케이션에만 프로퍼티 지정하고 싶다면 JNDI 프로퍼티 또는 JNDI 환경 값 사용을 고려해볼 만하다. 
  • JNDI에는 주로 DataSource 풀 같은 리소스를 바인딩해두고 이를 애플리케이션에서 가져와 사용하는 방법을 주로 사용한다. 

 

4) 서블릿 컨텍스트 파라미터 

  • 웹 애플리케이션 레벨의 프로퍼티 지정하고 싶긴 한데 서버에서 웹 애플리케이션 범위의 JNDI 값 설정하기 번거롭다면 web.xml에 서블릿 컨텍스트 초기 파라미터를 프로퍼티로 설정할 수 있다. 
  • 설정 방법은 <context-param>을 사용한다. 
  • 서블릿 컨텍스트 파라미터는 웹 애플리케이션 레벨에 프로퍼티를 둘 때 유용한 방법이지만 web.xml이 웹 애플리케이션에 포함되어 있기 때문에 환경에 따라 값을 지정하고 사용하기가 번거롭다는 단점이 있다. 

 

5) 서블릿 컨픽 파라미터 

  • 서블릿 컨텍스트는 서블릿이 소속된 웹 애플리케이션의 컨텍스트이고, 서블릿 컨픽은 개별 서블릿을 위한 설정이다. 
  • 서블릿 컨텍스트가 서블릿 컨픽보다 범위가 넗다. 
  • 서블릿 컨텍스트는 특정 서블릿에 소속되지 않은 루트 컨텍스트에도 주지만, 서블릿 컨픽은 해당 서블릿의 서블릿 컨텍스트에만 영향을 준다. 
  • 지금까지 살펴본 것 중에서 가장 범위가 좁다. 
  • <servlet> 안에 <init-param>으로 저징한다. 

 

프로퍼티 소스의 사용 

 

1) Environment.getProperty()

  • 가장 간단한 방법은 Environment 오브젝트를 빈에 주입받아서 직접 프로퍼티 값을 가져오는 것이다. 
  • @Autowired 이용하면 현재 컨텍스트에 만들어진 환경 오브젝트 사용할 수 있다. 

  • DB연결정보처럼 DataSource 빈을 만들 때 필요한 프로퍼티 정보를 @Configuration클래스에서 @Bean메소드로 DataSource빈을 만들고 주입해서 사용하면 된다. 

 

2) PropertySourceConfigurePlaceholder와 <context:property-placeholder>

  • @Value와 프로퍼티 ${} 치환자를 사용할 수도 있다. 

  • @Value에 치환자를 사용하려면 컨텍스트에 PropertySourcePlaceholderConfigurer빈이 등록되어 있어야 한다. 

 

3) @PropertySource와 프로퍼티 파일 

  • @PropertySource 애노테이션을 @Configuration클래스에 붙이고 프로퍼티 파일 위치를 기본 앨리머트 값으로 넣어주면 된다. 

 

1.6 요약 

  • 스프링 애플리케이션은 POJO클래스와 빈 설정 메타정보로 구성된다. 
  • 빈 설정 메타정보는 특정 포맷의 파일이나 리소스에 종속되지 않는다. 필요하다면 새로운 설정정보 작성 방법을 얼마든지 만들어 사용할 수 있다. 
  • 스프링의 빈 등록 방법은 크게 XML과 빈 자동인식, 자바 코드 세 가지로 구분할 수 있다. 
  • 스프링의 빈 의존관계 설정 방법은 XML과 애노테이션, 자바 코드로 구분할 수 있다. 
  • 프로퍼티 값은 빈에 주입되는 빈 오브젝트가 아닌 정보다. 
  • 프로퍼티 값 중에서 환경에 따라 자주 바뀌는 것은 프로퍼티 파일과 같은 별도의 리소스 형태로 분리해놓는 것이 좋다. 
  • 빈의 존재 범위인 스코프는 싱글톤과 프로토타입 그리고 기타 스코프로 구분할 수 있다. 
  • 프로토타입과 싱글톤이 아닌 스코프 빈은 DL 방식을 이용하거나, 스코프 프록시 빈을 DI 받는 방법을 사용해야 한다. 
  • 스프링 3.1은 애노테이션과 자바 코드를 이용한 빈 메타정보 작성 기능을 발전시켜서 자바코드만으로도 스프링 애플리케이션의 모든 빈 설정이 가능하게 해준다. 
  • 스프링 3.1의 프로파일과 프로퍼티 소스로 이뤄진 런타임 환경 추상화 기능을 이용하면 환경에 따라 달라지는 빈 구성과 속성 지정 문제를 손쉽게 다룰 수 있다. 
반응형