[Java-based Configuration]
: Java 코드와 스프링이 제공하는 어노테이션을 통해 스프링 컨테이너를 정의하는 방법 학습
[Declaring a Bean]
:@Configuration 어노테이션이 달린 클래스와 @Bean 어노테이션이 달린 메서드를 통해 Java 코드에서 스프링 빈을 등록할 수 있다.
빈으로 등록하고자 하는 함수의 리턴값에서 실제 구현체가 없으면 빈이 등록되지 않는다.
[Bean Dependencies]
:@Configuration 어노테이션이 있는 클래스 내의 메서드는 같은 클래스 내의 다른 @Bean 메서드를 호출해 빈 간의 의존성을 정의할 수 있다.
@Configuration
@ComponentScan(basePackages = "cholog.scan")
public class AppConfig {
@Bean
public AuthService authService() {
// 실제 구현체가 없으면 빈이 등록되지 않는다.
return new AuthService();
}
@Bean
public AuthenticationPrincipalArgumentResolver authenticationPrincipalArgumentResolver(AuthService authService) {
return new AuthenticationPrincipalArgumentResolver(authService);
}
}
[Property]
: 이는 애플리케이션의 구성값을 key-value 쌍으로 저장한다. 데이터베이스 연결 정보나 API 키 값을 예를 들 수 있다.
스프링의 Environment 인터페이스는 이와 같은 프로퍼티 소스들을 통합해 관리하고, 필요한 프로퍼티 값을 조회하는 기능을 제공한다.
[Using @PropertySource and Environment]
: @PropertySource 어노테이션을 사용해 프로퍼티 파일을 로드하고, Environment를 사용해 프로퍼티 값을 읽어올 수 있다.
// TODO: Java-based Configuration을 하기 위한 클래스로 지정하기
// TODO: ext-api.properties 파일을 활용하기 위한 설정 추가하기
@Configuration
@PropertySource("classpath:ext-api.properties")
public class PropertySourceConfig {
private final Environment env;
public PropertySourceConfig(Environment env) {
this.env = env;
}
// TODO: ext-api.properties의 google.api.endpoint 값을 Environment를 사용해서 가져오기
// TODO: 위 endpoint 값을 사용하여 GoogleMapsRestClient를 빈으로 등록하기
@Bean
public GoogleMapsRestClient googleMapsRestClient() {
String endpoint = env.getProperty("google.api.endpoint");
return new GoogleMapsRestClient(endpoint);
}
// TODO: ext-api.properties의 google.api.endpoint 값을 어노테이션을 사용해서 가져오기
// TODO: 위 endpoint 값을 사용하여 GoogleMapsRestClient를 빈으로 등록하기
public GoogleDriveRestClient googleDriveRestClient() {
return new GoogleDriveRestClient("");
}
}
이해가 잘 안된다..
[Using @PropertySource and @Value]
: @PropertySource를 사용해 로드한 프로퍼티 파일의 값을 @Value 어노테이션을 통해 주입할 수 있다.
스프링에서 @Value 어노테이션을 사용하면 ext-api.properties 파일에 있는 값을 필드나 메서드 파라미터에 주입할 수 있다.
package cholog.property.config;
import cholog.property.GoogleDriveRestClient;
import cholog.property.GoogleMapsRestClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
@Configuration
@PropertySource("classpath:ext-api.properties")
public class PropertySourceConfig {
private final Environment env;
public PropertySourceConfig(Environment env) {
this.env = env;
}
@Bean
public GoogleMapsRestClient googleMapsRestClient() {
String endpoint = env.getProperty("google.api.endpoint");
return new GoogleMapsRestClient(endpoint);
}
@Value("${google.api.endpoint}")
private String googleApiEndpoint;
@Bean
public GoogleDriveRestClient googleDriveRestClient() {
return new GoogleDriveRestClient(googleApiEndpoint);
}
}
[Externalized Configuration (Spring Boot)]
: 프로퍼티 값을 설정하는 방법은 @PropertySource 외에도 다양하다. 특히 Spring Boot 를 사용한다면 application.properties(혹은 application.yaml) 파일을 사용해 프로퍼티 값을 편하게 설정할 수 있다.
package cholog.property.config;
import cholog.property.JwtTokenKeyProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// TODO: Java-based Configuration을 하기 위한 클래스로 지정하기
@Configuration
public class AuthConfig {
// TODO: application.properties의 security.jwt.token.secret-key 값을 활용하여 JwtTokenKeyProvider를 빈으로 등록하기
@Value("${security.jwt.token.secret-key}")
private String secretKey;
@Bean
public JwtTokenKeyProvider jwtTokenKeyProvider() {
return new JwtTokenKeyProvider(secretKey);
}
}
[Profile]
: 프로파일은 애플리케이션 설정의 논리적인 그룹이다. 예를 들어, 개발(development), 테스트(testing), 운영(production)과 같이 다른 환경에 적합한 설정을 분리할 수 있다.
프로파일을 사용하면 같은 애플리케이션이지만 환경에 따라 다른 구성을 적용할 수 있다.
스프링이 제공하는 Environment 인터페이스는 현재 활성화되어 있는 프로파일과 기본 프로파일을 관리한다.
[@Profile]
: @Profile 어노테이션을 이용하여 특정 프로파일에 따라 빈을 등록할 수 있다. @Profile 어노테이션은 클래스 레벨, 메서드 레벨에 모두 적용 가능하다.
@Configuration 클래스에 적용하는 경우
클래스 내에서 정의된 Bean들은 development profile일 때만 등록된다.
@Bean 메서드에 적용하는 경우
profile에 따라 등록되는 Datasource Bean이 달라집니다.
@Configuration
public class ProfileConfig {
@Bean("dataSource")
@Profile("dev")
public MessageRepository inMemoryMessageRepository() {
return new InmemoryMessageRepository();
}
@Bean("dataSource")
@Profile("prod")
public MessageRepository jdbcMessageRepository() {
return new JdbcMessageRepository();
}
}
스프링 컨테이너를 정의하는 방법은 다양합니다.@Component, @Autowired 어노테이션을 사용하는 방법과 비교하여 Java 코드로 빈을 관리할 때의 장단점에 대해 생각해보고, 어떤 상황에서 어떤 방식을 택할지 고민해보세요.이 외에도 XML을 사용해 스프링 컨테이너를 정의할 수도 있습니다. XML을 사용하는 방법에 대해 알아보고, Java 코드와 XML을 사용하는 방법을 비교해보세요.Spring Boot는 프로퍼티 파일 컨벤션(application-{profile})을 사용해 활성 프로파일에 대한 프로퍼티 파일을 로드합니다. 예를 들어, 활성 프로파일이 prod 라면 application.properties, application-prod.properties 파일을 로드합니다. 이러한 특성을 사용해 어떤 값을 프로퍼티 파일에서 관리할지 생각해 보세요.
'프레임워크 > Spring' 카테고리의 다른 글
Java 애플리케이션 테스트 라이브러리: JUnit5 AssertJ (1) | 2024.10.01 |
---|---|
Spring Core 1 (0) | 2024.08.14 |
Spring JDBC(Java Database Connectivity) 1 (0) | 2024.08.12 |
Spring mvc 4 (MVC Configuration, View Controller, Interceptor, Argument Resolver) (0) | 2024.08.06 |
Spring mvc 3 (예외처리) (0) | 2024.08.05 |