@Profile과 @ActiveProfile
application.properties or yml에서 어떤 프로필을 사용할 지 결정할 수 있다.
spring.profiles.active=dev,local 이라고 명시하면 dev 프로필과 local 프로필을 사용하게 된다.
반면 Spring 코드 내에서 운영 환경에 따라 다른 빈을 주입해야 할 수도 있다.
메인 환경에서는 RedisMainConfig를 개발환경에서는 RedisDevConfig를 사용해 서로 다른 캐시를 사용해야 할 수도 있다.
또한 테스트 환경에서는 특정 프로필과 다른 프로필을 사용해야 할 수있다.
이럴 경우 @Profile 혹은 @ActiveProfile을 사용할 수 있다.
1. @Profile
@Profile은 환경에 따라 Bean의 로딩을 다르게 할 수 있는 기능이다.
사용법 1. 클래스 위에 붙인다.
@Configuration 이 붙은 클래스나 @Component, @Service, @Repository 등이 붙은 클래스 위에 붙일 수 있다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
@Profile("dev") // dev 환경에서만 적용
public class DevConfig {
@Bean
public DataSource dataSource() {
return new DataSource("jdbc:mysql://localhost:3306/dev_db");
}
}
위처럼 Config 파일 위에 명시하면 위 Config클래스는 dev 프로필일 경우에만 등록된다.
사용법 2. 메서드에 붙인다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
public class DataSourceConfig {
@Bean
@Profile("dev") // "dev" 환경에서만 활성화
public DataSource devDataSource() {
return new DataSource("jdbc:mysql://localhost:3306/dev_db", "dev_user", "dev_password");
}
@Bean
@Profile("prod") // "prod" 환경에서만 활성화
public DataSource prodDataSource() {
return new DataSource("jdbc:mysql://prod-db-url:3306/prod_db", "prod_user", "prod_password");
}
}
위와 같이 Configuration 파일 안에 메서드에 @Profile 을 붙여 사용할 수도 있다.
팁 1. 여러 프로필을 적용
참고로 {}를 활용해 여러 프로필을 적용할 수도 있다.
@Profile({"dev", "test"}) 이는 dev or test 환경에서 활성화된다.
팁 2. 특정 프로필 제외
!을 사용해서 특정 프로필을 제외하고 모든 환경에서 활성화할 수도 있다.
@Profile("!dev") 이는 dev환경 외에서 모두 활성화한다.
참고로 JpaRepository를 사용한 인터페이스에는 적용할 수 없다.
JpaRepository를 사용한 인터페이스에는 적용할 수 없다. JpaRepository를 상속한 인터페이스는 아래와 같이 애노테이션을 붙여도 작동하지 않는다.
@Profile("dev")
public interface MemberRepository extends JpaRepository<Member, Long> {
Optional<Member> findByEmail(String email);
boolean existsByEmail(String email);
}
JpaRepository를 구현한 인터페이스에 대해서는 Spring Data JPA가 실제 구현체를 만들어줘서 프록시로 등록해 사용한다.
이 때 인터페이스가 아니라, 프록시를 사용하기 때문에 @Profile 애노테이션은 구현체에 붙지 않는다.
그래서 만약 @Profile 애노테이션을 붙이고 싶으면 직접 Repository를 구현해야 한다.
2. @ActiveProfiles
@ActiveProfiles란 테스트 환경에서 어떤 프로필을 사용할 지 결정하는 애노테이션이다. 즉 별도로 spring.profiles.active = test 지정하지 않아도 테스트에서 특정 프로필을 적용할 수 있다.
@SpringBootTest
@ActiveProfiles("test") // 테스트 실행 시 "test" 프로파일 활성화
public class DataSourceTest {
@Test
void testDataSource() {
// 테스트 코드 실행 시 "test" 프로파일이 적용됨
}
}
3. @Profile의 동작과정
Spring은 초기 실행될 때 현재 활성화된 프로필 목록을 내부적으로 저장해둔다.
이 후 빈을 스캔하여 등록할 때 @Profile 확인하여 설정된 빈과 일치하는 지 체크한다. 만약 맞지 않으면 빈을 제외한다.
'Spring' 카테고리의 다른 글
영속성 컨텍스트의 1차 캐시는 어떻게 저장될까? (0) | 2025.02.22 |
---|---|
@Transactional 내에서가 아니여도 OSIV가 on이면 조회한 데이터들이 같은 영속성 컨텍스트를 공유하는 이유 (0) | 2025.02.22 |
Spring에서의 예외, 에러 처리 (0) | 2024.11.02 |
Spring에서의 프로세스와 스레드 (0) | 2024.10.21 |
Spring에서 @Async를 통한 비동기 처리하기 (0) | 2024.09.26 |