스프링 Profile
스프링 프로파일은 애플리케이션 설정 일부를 분리하여 특정 환경에서만 사용 가능케합니다. 프로파일을 이용하면 여러 빈 정의들이 특정 프로파일에서만 동작하게 할수도 있고 특정 프로퍼티들을 특정 프로파일로 정의해서 해당 프로파일이 엑티브일때 적용되게 할 수도 있습니다. 그럼 빈 정의와 프로퍼티들에 프로파일을 적용해 보겠습니다.
우선 빈 정의시 프로파일을 적용해 보겠습니다.
@Repository @Profile("local") public class MemoryVoucherRepository implements VoucherRepository, InitializingBean {
@Repository @Profile("dev") public class JdbcVoucherRepository implements VoucherRepository {
package org.prgrms.kdt; import org.prgrms.kdt.order.OrderItem; import org.prgrms.kdt.order.OrderProperties; import org.prgrms.kdt.order.OrderService; import org.prgrms.kdt.order.VersionProvider; import org.prgrms.kdt.voucher.FixedAmountVoucher; import org.prgrms.kdt.voucher.JdbcVoucherRepository; import org.prgrms.kdt.voucher.VoucherRepository; import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.util.Assert; import java.text.MessageFormat; import java.util.*; public class OrderTester { public static void main(String[] args) { // 프로페익을 적용하고 리플레쉬를 해줘야합니다. 안그러면 이미 디폴트 프로파일로 읽어져서 원하는 결과를 얻을 수 없습니다. var applicationContext = new AnnotationConfigApplicationContext(); applicationContext.getEnvironment().setActiveProfiles("dev");; applicationContext.register(AppConfiguration.class); applicationContext.refresh(); var orderService = applicationContext.getBean(OrderService.class); var voucherRepository = applicationContext.getBean(VoucherRepository.class); System.out.println(MessageFormat.format("is JdbcRepo -> {0}", voucherRepository instanceof JdbcVoucherRepository)); System.out.println(MessageFormat.format("is JdbcRepo -> {0}", voucherRepository.getClass().getCanonicalName())); var voucher = voucherRepository.insert(new FixedAmountVoucher(UUID.randomUUID(), 10L)); var order = orderService.createOrder(UUID.randomUUID(), new ArrayList<OrderItem>() {{ add(new OrderItem(UUID.randomUUID(), 100, 1)); }}, voucher.getVoucherId()); Assert.isTrue(order.totalAmount() == 90L, MessageFormat.format("totalAmount({0}) is not 90L", order.totalAmount())); } }
다음으로 프로파일에 적용해 보겠습니다.
servers: - dev.bar.com - foo.bar.com --- spring.config.activate.on-profile: local kdt: version: v1.0 support-vendors: - "a" - "b" - "c" - "d" minimum-order-amount: 1 description: |- #-에 따라 마지막 줄마꿈이 포함되거나 안포함된다. -있으면 안포함 line 1 line 2 line 3 --- spring.config.activate.on-profile: dev kdt: version: v1.0-dev support-vendors: - "dev-a" - "dev-b" minimum-order-amount: 0 description: |- dev
var applicationContext = new AnnotationConfigApplicationContext(); applicationContext.getEnvironment().setActiveProfiles("dev");; applicationContext.register(AppConfiguration.class); applicationContext.refresh(); var version = applicationContext.getEnvironment().getProperty("kdt.version"); var supportVendors = applicationContext.getEnvironment().getProperty("kdt.support-vendors"); var description = applicationContext.getEnvironment().getProperty("kdt.description"); System.out.println(MessageFormat.format("getVersion from env -> {0}", version)); System.out.println(MessageFormat.format("supportVendors from env -> {0}", supportVendors)); System.out.println(MessageFormat.format("description from env -> {0}", description)); var orderProperties = applicationContext.getBean(OrderProperties.class); System.out.println(MessageFormat.format("getVersion -> {0}", orderProperties.getVersion())); System.out.println(MessageFormat.format("getMinimumOrderAmount -> {0}", orderProperties.getMinimumOrderAmount())); System.out.println(MessageFormat.format("getSupportVendors -> {0}", orderProperties.getSupportVendors())); System.out.println(MessageFormat.format("description -> {0}", orderProperties.getDescription()));
dev → local로 변경하면 이상하게 프로퍼티는 안바뀌지만 주입되는 빈은 변경되는 것을 볼 수있습니다. 스프링 프레임워크는 프로파일에 대한 빈 정의 만을 지원하고 사실 프로파일별 프로퍼티에 대한 변경은 스프링부트에서 지원하는 기능입니다.
스프링부트의 SpringApplication를 사용하기 전에 우선 활성 프로파일을 정의할수 있는 다른 방법들을 보겠습니다.
스프링 활성 프로파일에 대한 정의는 다양한 곳에서 가능합니다. 방금 한 것 처럼 애플리케이션 코드상에 직접 세팅할 수도 있지만
JVM의 시스템 속성
,명령줄 인수
, OS의 환경변수
, 프로퍼티의 속성
에서도 가능합니다.하나씩 한번 살펴보도록 할게요.

.png?table=block&id=1e666451-1db7-49d5-b650-9bdf0e3f7e3f&cache=v2)
.png?table=block&id=127292eb-f63a-4337-87b3-16a09c32c46d&cache=v2)
그럼 이제 KdtApplication 을 변경해볼가요.
package org.prgrms.kdt; import org.prgrms.kdt.order.Order; import org.prgrms.kdt.order.OrderProperties; import org.prgrms.kdt.order.OrderRepository; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import java.text.MessageFormat; @SpringBootApplication @ComponentScan(basePackages = {"org.prgrms.kdt.order", "org.prgrms.kdt.voucher", "org.prgrms.kdt.config"}) public class KdtApplication { public static void main(String[] args) { var context = SpringApplication.run(KdtApplication.class, args); var orderProperties = context.getBean(OrderProperties.class); System.out.println(MessageFormat.format("getVersion -> {0}", orderProperties.getVersion())); System.out.println(MessageFormat.format("getMinimumOrderAmount -> {0}", orderProperties.getMinimumOrderAmount())); System.out.println(MessageFormat.format("getSupportVendors -> {0}", orderProperties.getSupportVendors())); System.out.println(MessageFormat.format("getDescription -> {0}", orderProperties.getDescription())); } }
코드상에서 변경하려면 다음과 같이 해야합니다.
var springApplication = new SpringApplication(KdtApplication.class); springApplication.setAdditionalProfiles("dev"); var context = springApplication.run();
.png?table=block&id=510c59a3-22c2-46e3-9ebb-1b7f530755fc&cache=v2)
.png?table=block&id=7cb08a46-d647-40d0-a12b-5a6c6b8a9700&cache=v2)