- 애노테이션 직접 만들기
- @Qualifier("mainDiscountPolicy") 이렇게 문자를 적으면 컴파일 시 타입 체크가 안됨.
- 이런 경우 애노테이션을 직접 만들어서 해결 가능
- 애노테이션은 상속이라는 개념이 없음
- 여러 애노테이션을 모아서 사용하는 기능은 스프링이 지원하는 기능인 것.
- Autowired도 재정의 가능. 하지만 스프링이 제공하는 기능을 뚜렷한 목적 없이 무분별하게 재정의 하면 유지 보수에 혼란을 줄 수 있으므로 삼가자.
- 조회한 빈이 모드 필요할 때, List, Map
- 예제
- 할인 서비스 제공 시, 클라이언트가 할인의 종류를 선택할 수 있다고 가정
- 스프링을 사용하면 전략 패턴 간단히 구현 가능
public class AllBeanTest {
@Test
void findAllBean(){
ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class);
DiscountService discountService = ac.getBean(DiscountService.class);
Member member = new Member(1L, "USERA", Grade.VIP);
int discountPrice = discountService.discount(member, 10000, "rateDiscountPolicy");
assertThat(discountService).isInstanceOf(DiscountService.class);
assertThat(discountPrice).isEqualTo(1000);
}
static class DiscountService{
private final Map<String, DiscountPolicy> policyMap;
private final List<DiscountPolicy> policies;
@Autowired
public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> policies) {
this.policyMap = policyMap;
this.policies = policies;
System.out.println("policyMap : "+policyMap);
System.out.println("policies : "+ policies);
}
public int discount(Member member, int price, String discountCode) {
DiscountPolicy discountPolicy = policyMap.get(discountCode);
return discountPolicy.discount(member, price);
}
}
}
- 자동, 수동의 올바른 실무 운영 기준
- 편리한 자동 기능을 기본으로 사용하기
- 어떤 경우에 컴포넌트 스캔과 자동 주입을 사용하고 어떤 경우에 수동으로 빈을 등록하고 의존관계도 수동으로 주입해야 할까?
- 점점 자동 선호 추세
- 설정 정보를 기반으로 애플리케이션을 구성하는 부분과 실제 동작하는 부분을 명확하게 나누는 것이 이상적
- 하지만 개발자 입장에서 스프링 빈을 하나 등록할 때 @Component만 넣으면 끝날텐데 하나하나 @Configuration 설정 정보에 가서 @ Bean을 적고 객체 생ㅇ성, 주입할 대상을 일ㅇ리이 적어주는 과정은 번거롭고 설정 정보를 관리하는 것이 부담스러워짐
- 자동으로 등록해도 OCP, DIP 지키는 것도 가능하니 자동을 점점 선호하는 것
- 수동은 언제 사용할까?
- 애플리케이션 = 업무로직 + 기술 지원로직으로 나뉨
- 업무 로직 빈 : 웹을 지원하는 컨트롤러, 핵심 비즈니스 로직이 있는 서비스, 데이터 계층의 로직을 처리하는 리포지토리 등이 모두 업무 로직. 이는 비즈니스 요구사항을 개발할 때 추가되거나 변경 됨.
- 기술 지원 빈 : 기술적인 문제나 공통 관심사(AOP)를 처리할 때 주로 사용됨. 데이터베이스 ㅇ연결이나 공통 로그 처리 처럼 업무 로직을 지원하기 위한 하부 기술이나 공통 기술들
- 업무로직은 매우 많고 한번 개발해야 하면 컨트롤러, 서비스, 리포지토리처럼 유사한 패턴이 존재하므로 이런 경우 자동기능 적극 사용 괜찮음. 문제가 발생해도 문제 명확하게 파악하기 쉬운 편
- 기술 지원로직은 업무 로직에 비해 수가 적고, 문제 발생 시 애플리케이션 전반에 광범위하게 영향을 미치므로 가급적 수동 빈 등록을 하여 명확히 밖으로 드러내는 것이 좋음.
- 비즈니스 로직 중 다형성 적극 사용 시!
- 의존관계 자동 주입 시, 조회한 빈이 모두 필요할 때 List, Map 다시 보기
- 다형성을 적극 활용할 때 각 빈들의 이름이 무엇일지, 코드만 보고 한번에 쉽게 파악하기 어려움. 특히 다른 개발자가 짠 코드를 파악하려면 더욱 어려울 것. 따라서 이런 경우 수동 빈으로 등록하거나 자동으로 한다면 특정 패키지에 같이 묶어두는 것이 좋음.
- 스프링과 스프링 부트가 자동으로 등록하는 빈들은 예외.
- 스프링의 의도대로 사용하는 것이 좋음. ex. DataSource
- 어떤 경우에 컴포넌트 스캔과 자동 주입을 사용하고 어떤 경우에 수동으로 빈을 등록하고 의존관계도 수동으로 주입해야 할까?