Skip to main content

Spring Core 2

1. Java-based Configuration

spring-core-1에서는 @Component, @Autowired 어노테이션을 사용해 스프링 빈을 생성하고 빈간 의존성을 주입하는 방법을 익혔습니다.

이 문서에서는 Java 코드와 스프링이 제공하는 어노테이션을 사용해 스프링 컨테이너를 정의하는 법을 알아봅니다.

1.1. Declaring a Bean

@Configuration 어노테이션이 달린 클래스와 @Bean 어노테이션이 달린 메서드를 통해 Java 코드에서 스프링 빈을 등록할 수 있습니다.

가장 단순한 @Configuration 클래스는 다음과 같습니다.

@Configuration
public class AppConfig {
@Bean
public MyServiceImpl myService() {
return new MyServiceImpl();
}
}

학습 테스트

  • 테스트 메서드: cholog.configuration.ConfigTest.shouldCreateBean
  • 수행 방법
    • cholog.configuration.config.AppConfig 클래스를 이용하여 학습 테스트를 성공시키세요.

1.2 Bean Dependencies

@Configuration 어노테이션이 있는 클래스 내의 메서드는 같은 클래스 내의 다른 @Bean 메서드를 호출하여 빈 간의 의존성을 정의할 수 있습니다.

@Configuration
public class AppConfig {

@Bean
public BeanOne beanOne() {
return new BeanOne(beanTwo());
}

@Bean
public BeanTwo beanTwo() {
return new BeanTwo();
}
}

다른 @Configuration 클래스 내의 빈을 사용해서도 의존성을 정의할 수 있습니다. 이 방법에 대해서는 Spring - Bean Dependencies 문서를 참고해 주세요.

학습 테스트

  • 테스트 메서드: cholog.configuration.ConfigTest.shouldCreateBeansThatHasDependency
  • 수행 방법
    • cholog.configuration.config.AppConfig 클래스를 이용하여 학습 테스트를 성공시키세요.

2. Property

프로퍼티는 애플리케이션의 구성값을 키-값 쌍으로 저장합니다. 예를 들어, 데이터베이스 연결 정보나 API 키 같은 설정값입니다.

스프링의 Environment 인터페이스는 이러한 프로퍼티 소스들을 통합하여 관리하고, 필요한 프로퍼티 값을 조회하는 기능을 제공합니다.

2.1. Using @PropertySource and Environment

@PropertySource 어노테이션을 사용해 프로퍼티 파일을 로드하고 Environment를 사용해 프로퍼티 값을 읽어올 수 있습니다.

@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {

@Autowired
Environment env;

@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}

학습 테스트

  • 테스트 메서드: cholog.property.PropertySourceConfigTest.getPropertyValueFromUsingEnvironment
  • 수행 방법
    • cholog.property.config.PropertySourceConfig 클래스를 이용하여 학습 테스트를 성공시키세요.

2.2. Using @PropertySource and @Value

@PropertySource를 사용해 로드한 프로퍼티 파일의 값을 @Value 어노테이션을 통해 주입할 수 있습니다.

@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
@Bean
public TestBean testBean(@Value("${testbean.name}") String name) {
TestBean testBean = new TestBean();
testBean.setName(name);
return testBean;
}
}

학습 테스트

  • 테스트 메서드: cholog.property.PropertySourceConfigTest.getPropertyValueFromUsingAnnotation
  • 수행 방법
    • cholog.property.config.PropertySourceConfig 클래스를 이용하여 학습 테스트를 성공시키세요.

2.3. Externalized Configuration (Spring Boot)

프로퍼티 값을 설정하는 방법은 @PropertySource 외에도 다양합니다.

특히 Spring Boot 를 사용한다면 application.properties(혹은 application.yaml) 파일을 사용해 프로퍼티 값을 편하게 설정할 수 있습니다.

학습 테스트

  • 테스트 메서드: cholog.property.ConfigDataFileTest.getPropertyValueWithSpringBoot
  • 수행 방법
    • cholog.property.config.AuthConfig 클래스를 이용하여 학습 테스트를 성공시키세요.

3. Profile

프로파일은 애플리케이션 설정의 논리적인 그룹입니다. 예를 들어, 개발(development), 테스트(testing), 운영(production)과 같이 다른 환경에 적합한 설정을 분리할 수 있습니다.

프로파일을 사용하면 같은 애플리케이션이지만 환경에 따라 다른 구성을 적용할 수 있습니다.

스프링이 제공하는 Environment 인터페이스는 현재 활성화되어 있는 프로파일과 기본 프로파일을 관리합니다.

3.1. @Profile

@Profile 어노테이션을 이용하여 특정 프로파일에 따라 빈을 등록할 수 있습니다. @Profile 어노테이션은 클래스 레벨, 메서드 레벨에 모두 적용 가능합니다.

@Configuration 클래스에 적용하는 경우

클래스 내에서 정의된 Bean들은 development profile일 때만 등록됩니다.

@Configuration
@Profile("development")
public class StandaloneDataConfig {

@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}

@Bean 메서드에 적용하는 경우

profile에 따라 등록되는 Datasource Bean이 달라집니다.

@Configuration
public class AppConfig {

@Bean("dataSource")
@Profile("development")
public DataSource standaloneDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}

@Bean("dataSource")
@Profile("production")
public DataSource jndiDataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}

학습 테스트

  • 테스트 메서드:
    • cholog.profile.ProfileConfigTest.shouldCreateInmemoryRepositoryBean
    • cholog.profile.ProfileConfigTest.shouldCreateJdbcRepositoryBean
  • 수행 방법
    • cholog.profile.config.ProfileConfig 클래스를 이용하여 학습 테스트를 성공시키세요.

4. 더 생각해보기

  • 스프링 컨테이너를 정의하는 방법은 다양합니다.@Component, @Autowired 어노테이션을 사용하는 방법과 비교하여 Java 코드로 빈을 관리할 때의 장단점에 대해 생각해보고, 어떤 상황에서 어떤 방식을 택할지 고민해보세요.
  • 이 외에도 XML을 사용해 스프링 컨테이너를 정의할 수도 있습니다. XML을 사용하는 방법에 대해 알아보고, Java 코드와 XML을 사용하는 방법을 비교해보세요.
  • Spring Boot는 프로퍼티 파일 컨벤션(application-{profile})을 사용해 활성 프로파일에 대한 프로퍼티 파일을 로드합니다. 예를 들어, 활성 프로파일이 prod 라면 application.properties, application-prod.properties 파일을 로드합니다. 이러한 특성을 사용해 어떤 값을 프로퍼티 파일에서 관리할지 생각해 보세요.

5. 참고자료