AppConfig는 애플리케이션의 설정(Configuration) 클래스로, Spring이 관리하는 Bean 객체를 등록하고 의존성을 주입하는 역할을 합니다. 보통 Spring의 DI(Dependency Injection, 의존성 주입)를 설정하는 핵심 클래스로 사용됩니다.
1️⃣ AppConfig가 필요한 이유
❌ 기존 방식 (XML 기반 설정)
과거에는 Spring 설정을 XML 파일(applicationContext.xml)로 작성했지만, 유지보수가 어렵고 가독성이 떨어졌음
✅ Java 기반 설정 (@Configuration + @Bean)
Spring Boot 이후로는 Java 클래스로 설정을 관리하는 방법이 등장함
- 가독성이 뛰어나고 유지보수가 쉬움
- XML 설정이 필요 없음
- 객체 간의 관계를 명확하게 설정 가능
2️⃣ AppConfig의 기본 구조
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration // 이 클래스를 Spring 설정 클래스로 지정
public class AppConfig {
@Bean // 스프링 컨테이너가 관리하는 Bean 객체 등록
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository(); // 구현체를 변경할 때 이 부분만 수정하면 됨
}
}
📌 주요 어노테이션 설명
- @Configuration: Spring의 설정 클래스임을 나타냄
- @Bean: Spring 컨테이너가 관리하는 객체(Bean)를 생성하고 등록함
3️⃣ AppConfig를 사용한 DI(의존성 주입)
📌 AppConfig를 사용하면 무엇이 달라질까?
- 기존에는 생성자 주입 없이 직접 객체를 생성했음
- AppConfig를 활용하면 객체 간의 관계를 한 곳에서 관리할 수 있음
✅ 기존 방식 (직접 객체 생성)
MemberService memberService = new MemberServiceImpl();
MemberRepository memberRepository = new MemoryMemberRepository();
→ 객체 간의 의존성이 강해짐 (강한 결합, Tight Coupling).
✅ AppConfig를 활용한 방식
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = context.getBean("memberService", MemberService.class);
→ Spring 컨테이너에서 관리하는 Bean을 가져와 사용 (느슨한 결합, Loose Coupling)
→ 객체 생성의 책임을 Spring 컨테이너에 위임하여 테스트 및 유지보수 용이
4️⃣ AppConfig를 활용한 DI 패턴
✅ 1. DIP (Dependency Inversion Principle) 적용
- AppConfig를 통해 구현체를 변경해도 클라이언트 코드에는 영향이 없음
- 즉, 인터페이스(MemberRepository)에만 의존하도록 설계할 수 있음
✅ 2. OCP (Open-Closed Principle) 적용
- 기존 코드를 수정하지 않고 확장 가능함
- 예를 들어, MemoryMemberRepository에서 JdbcMemberRepository로 변경할 때 AppConfig만 수정하면 됨
@Bean
public MemberRepository memberRepository() {
return new JdbcMemberRepository(); // 변경 가능
}
5️⃣ AppConfig의 실제 사용 예시
📌 AppConfig 설정
@Configuration
public class AppConfig {
@Bean
public OrderService orderService() {
return new OrderServiceImpl(orderRepository());
}
@Bean
public OrderRepository orderRepository() {
return new JdbcOrderRepository(); // 구현체 변경 시 이 부분만 수정
}
}
📌 Main에서 ApplicationContext로 사용하기
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
OrderService orderService = context.getBean("orderService", OrderService.class);
// 서비스 메서드 실행
orderService.createOrder(1L, "상품A", 10000);
}
}
6️⃣ @ComponentScan과 함께 사용
보통 @ComponentScan을 사용하면 @Bean을 직접 등록하지 않고 자동으로 찾아줌
하지만 명확한 의존성 설정이 필요할 경우 @Configuration을 사용한 AppConfig 방식이 더 좋음
@Configuration
@ComponentScan(basePackages = "com.example") // com.example 패키지의 모든 컴포넌트를 자동 스캔
public class AutoAppConfig {
}
🔥 정리
설정 방식 | 특징 | 사용 용도 |
@Configuration + @Bean | 명확한 의존성 관리, 유지보수 용이 | 의존성 주입이 중요한 경우 (객체 생성과 관계 명확화) |
@ComponentScan + @Component | 자동 스캔, 설정 최소화 | 단순한 서비스나 레포지토리 등록 시 |
결론적으로 AppConfig는 Spring에서 의존성 주입을 효율적으로 관리하는 핵심 설정 클래스입니다.
1️⃣ @Configuration + @Bean을 사용하면 객체 간의 관계를 명확하게 설정할 수 있습니다.
2️⃣ DIP와 OCP 원칙을 지켜 유지보수성과 확장성이 뛰어납니다.
3️⃣ ApplicationContext를 사용하여 Spring 컨테이너에서 객체를 주입받아 사용 가능합니다.
4️⃣ @ComponentScan을 함께 사용할 수도 있지만, 명확한 설정이 필요할 때 AppConfig를 직접 작성하는 것이 더 좋습니다.
'개발일지 > Spring' 카테고리의 다른 글
스프링 컨테이너 생성 과정 (0) | 2025.02.13 |
---|---|
Spring Bean (0) | 2025.02.07 |
동시성 문제를 고려한 HashMap<>() 선택하기 (0) | 2025.02.07 |
객체지향원칙을 고려한 Spring 테스트 설계 전략 (JUnit) (0) | 2025.02.06 |
Spring 테스트 케이스 작성 방법과 팁 (JUnit) (2) | 2025.02.06 |