λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
⭐ Personal_Study/Spring

μ˜μ‘΄κ΄€κ³„ μžλ™ μ£Όμž…

by ν¬μŠ€νŠΈμ‰μ΄ν¬ 2023. 1. 9.

μ˜μ‘΄κ΄€κ³„ μžλ™ μ£Όμž…

1. λ‹€μ–‘ν•œ μ˜μ‘΄κ΄€κ³„ μ£Όμž… 방법

  1. μƒμ„±μž μ£Όμž…(constructor) βœ”
  2. μˆ˜μ •μž μ£Όμž…(setter)
  3. ν•„λ“œ μ£Όμž…
  4. 일반 λ©”μ„œλ“œ μ£Όμž…

1. μƒμ„±μž μ£Όμž…

μƒμ„±μž 호좜 μ‹œμ μ— λ”± 1번만 ν˜ΈμΆœλ˜λŠ” 것 보μž₯

βœ” λΆˆλ³€, ν•„μˆ˜ μ˜μ‘΄κ΄€κ³„μ— μ‚¬μš©

// OrderServiceImpl.java

@Component
public class OrderServiceImpl implements OrderService{

//    final -> λ°˜λ“œμ‹œ 값을 ν• λ‹Ήν•΄μ€˜μ•Όν•œλ‹€.(ν•„μˆ˜, λΆˆλ³€)
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;


    @Autowired // μƒμ„±μžκ°€ ν•œ 개만 μžˆμ„ 경우 μƒλž΅ν•΄λ„ λœλ‹€.
    public OrderServiceImpl(MemberRepository memberRepository, @MainDiscountPolicy  DiscountPolicy discountPolicy) {
//        System.out.println("memberRepository = " + memberRepository);
//        System.out.println("discountPolicy = " + discountPolicy);
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
    ...
}

μƒμ„±μžκ°€ ν•œ 개만 μžˆμ„ 경우 `@Autowired μƒλž΅ κ°€λŠ₯

2. μˆ˜μ •μž μ£Όμž…(Setter μ£Όμž…)

ν•„λ“œμ˜ 값읍 λ³€κ²½ν•˜λŠ” μˆ˜μ •μž λ©”μ„œλ“œμΈ setterλ₯Ό ν†΅ν•΄μ„œ 의쑴 관계 μ£Όμž…

선택, λ³€κ²½ κ°€λŠ₯성이 μžˆλŠ” μ˜μ‘΄κ΄€κ³„μ— μ‚¬μš©
μžλ°”λΉˆ ν”„λ‘œνΌν‹° κ·œμ•½μ˜ μˆ˜μ •μž λ©”μ„œλ“œ μ‚¬μš©

// OrderServiceImpl.java

@Component

public class OrderServiceImpl implements OrderService{


    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

    @Autowired
    public void setMemberRepository(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Autowired
    public void setDiscountPolicy(DiscountPolicy discountPolicy) {
        this.discountPolicy = discountPolicy;
    }
    ...
}

β€» μžλ°”λΉˆ ν”„λ‘œνΌν‹° κ·œμ•½: ν•„λ“œμ˜ 값을 직접 λ³€κ²½ν•˜μ§€ μ•Šκ³  setterλž‘ getter λ©”μ„œλ“œλ₯Ό ν™œμš©ν•΄ 값을 μ½κ±°λ‚˜ μˆ˜μ •ν•˜λŠ” κ·œμΉ™

3. ν•„λ“œ μ£Όμž…

μ½”λ“œκ°€ 맀우 κ°„κ²°ν•˜λ‚˜ μ™ΈλΆ€μ—μ„œ 변경이 λΆˆκ°€λŠ₯ν•΄ ν…ŒμŠ€νŠΈν•˜κΈ° νž˜λ“€λ‹€!

가급적 μ‚¬μš© 자제!!

ν…ŒμŠ€νŠΈμ½”λ“œλ‚˜ μŠ€ν”„λ§ μ„€μ • λͺ©μ μœΌλ‘œ ν•˜λŠ” @Configuration같은 κ³³μ—μ„œλ§Œ νŠΉλ³„ν•œ μš©λ„λ‘œ μ‚¬μš©

// OrederServiceImpl.java

@Component
public class OrderServiceImpl implements OrderService {

    @Autowired
    private MemberRepository memberRepository;
    @Autowired
    private DiscountPolicy discountPolicy;
}

4.일반 λ©”μ„œλ“œ μ£Όμž…

ν•œλ²ˆμ— μ—¬λŸ¬ ν•„λ“œλ₯Ό μ£Όμž… 받을 수 μžˆμœΌλ‚˜ 잘 μ‚¬μš©ν•˜μ§€λŠ” μ•ŠλŠ”λ‹€!

@Component
public class OrderServiceImpl implements OrderService {

    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

    @Autowired
    public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

}

2. μ˜΅μ…˜μ²˜λ¦¬

μ£Όμž…ν•  μŠ€ν”„λ§ 빈이 없어도 λ©”μ„œλ“œλ₯Ό λ™μž‘ν•˜κ²Œ ν•˜κ³  싢을 경우 μ˜΅μ…˜ 처리λ₯Ό ν•΄μ•Όν•œλ‹€.

μ˜΅μ…˜ 처리 방법

  • @Autowired(required=false) : μžλ™ μ£Όμž…ν•  λŒ€μƒμ΄ μ—†μœΌλ©΄ μˆ˜μ •μž λ©”μ„œλ“œ μžμ²΄κ°€ 호좜 μ•ˆλ¨
  • org.springframework.lang.@Nullable : μžλ™ μ£Όμž…ν•  λŒ€μƒμ΄ μ—†μœΌλ©΄ null이 μž…λ ₯λœλ‹€.
  • Optional<> : μžλ™ μ£Όμž…ν•  λŒ€μƒμ΄ μ—†μœΌλ©΄ Optional.empty κ°€ μž…λ ₯λœλ‹€
// AutowiredTest.java

public class AutowiredTest {

    @Test
    void AutowiredOption() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestBean.class);
    }

    static class TestBean {

        // μŠ€ν”„λ§ λΉˆμ— λ“±λ‘λ˜μ§€ μ•Šμ€ λŒ€μƒ μ£Όμž…ν•΄λ³΄κΈ° (Member)

        // 1. 의쑴 관계가 μ—†μœΌλ©΄ μ•„μ˜ˆ 호좜이 μ•ˆλœλ‹€
        @Autowired(required = false)
        public void setNoBean1(Member noBean1) {
            System.out.println("noBean1 = " + noBean1);
        }

        // 2. null둜 호좜
        @Autowired
        public void setNoBean2(@Nullable Member noBean2) {
            System.out.println("noBean2 = " + noBean2);
        }

        // 3. Optional.empty 호좜
        @Autowired
        public void setNoBean3(Optional<Member> noBean3) {
            System.out.println("noBean3 = " + noBean3);
        }
    }
}
// ν…ŒμŠ€νŠΈ κ²°κ³Ό

// 1. 은 호좜이 μ•ˆλœλ‹€
noBean2 = null
noBean3 = Optional.empty

3. μƒμ„±μž μ£Όμž…μ„ μ„ νƒν•˜λΌ

μ΅œκ·Όμ—λŠ” μƒμ„±μž μ£Όμž…μ΄ ꢌμž₯λœλ‹€

λΆˆλ³€

βœ” λŒ€λΆ€λΆ„ 의쑴 관계 μ£Όμž…μ€ ν•œλ²ˆ μΌμ–΄λ‚˜λ©΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ’…λ£Œμ‹œμ κΉŒμ§€ λ³€κ²½ν•  일이 μ—†μœΌλ©° ꢌμž₯λ˜μ§€ μ•ŠλŠ”λ‹€

μˆ˜μ •μž μ£Όμž…μ„ μ‚¬μš©ν•˜λ©΄ setter λ©”μ„œλ“œλ₯Ό public으둜 열여두어야 ν•œλ‹€

  • λˆ„κ΅°κ°€ μ‹€μˆ˜λ‘œ λ³€κ²½ κ°€λŠ₯
  • λ³€κ²½ μ•ˆλ˜λŠ” λ©”μ„œλ“œλ₯Ό μ—΄μ–΄λ‘λŠ” 것은 지양

μƒμ„±μž μ£Όμž…μ€ 객체 생성 μ‹œμ—λ§Œ 1번 호좜되고 이후에 ν˜ΈμΆœλ˜μ§€ μ•ŠλŠ”λ‹€ -> λΆˆλ³€ 섀계

λˆ„λ½**

ν”„λ ˆμž„μ›Œν¬ 없이 μˆœμˆ˜ν•œ μžλ°” μ½”λ“œ λ‹¨μœ„λ‘œ μ‹€ν–‰ μ‹œ(@Autowired λ™μž‘ x)

  • μˆ˜μ •μž μ£Όμž…μ—μ„œλŠ” 싀행은 λ˜λ‚˜ NPEλ°œμƒ
  • μƒμ„±μž λ©”μ„œλ“œμ—μ„œλŠ” 컴파일 였λ₯˜ λ°œμƒ -> 디버깅 용이

final

μƒμ„±μž μ£Όμž… μ‚¬μš© μ‹œ ν•„λ“œμ— final ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€ -> μƒμ„±μžμ—μ„œ 값이 μ„€μ •λ˜μ§€ μ•ŠλŠ” 였λ₯˜λ₯Ό 컴파일 μ‹œμ μ— μž‘μ•„μ€€λ‹€

μ˜ˆμ‹œ μ½”λ“œ

@Component
public class OrderServiceImpl implements OrderService {

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    // discountPolicy λˆ„λ½
    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
    }
 //...
}

컴파일 였λ₯˜: java: variable discountPolicy might not have been initialized

β€» μ°Έκ³ : μˆ˜μ •μž μ£Όμž…μ„ ν¬ν•¨ν•œ λ‚˜λ¨Έμ§€ μ£Όμž… 방식은 λͺ¨λ‘ μƒμ„±μž 이후에 ν˜ΈμΆœλ˜λ―€λ‘œ, ν•„λ“œμ— final ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€. 였직 μƒμ„±μž μ£Όμž… λ°©μ‹λ§Œ final ν‚€μ›Œλ“œλ₯Ό μ‚¬μš© κ°€λŠ₯

4. 둬볡과 μ΅œμ‹  νŠΈλ Œλ“œ

맀번 μƒμ„±μž μ£Όμž… μ½”λ“œ μž‘μ„±ν•˜κΈ° λ²ˆκ±°λ‘­λ‹€! -> 둬볡 라이브러리 ν™œμš©

둬볡 라이브러리 μ„€μΉ˜ 방법

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.7.7'
    id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

//lombok μ„€μ • μΆ”κ°€ μ‹œμž‘
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
//lombok μ„€μ • μΆ”κ°€ 끝

dependencies {

    //lombok 라이브러리 μΆ”κ°€ μ‹œμž‘
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'
    //lombok 라이브러리 μΆ”κ°€ 끝

    implementation 'org.springframework.boot:spring-boot-starter'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

}

tasks.named('test') {
    useJUnitPlatform()
}
  1. Preferences(μœˆλ„μš° File Settings) plugin lombok 검색 μ„€μΉ˜ μ‹€ν–‰ (μž¬μ‹œμž‘)
  2. Preferences Annotation Processors 검색 Enable annotation processing 체크 (μž¬μ‹œμž‘)
  3. μž„μ˜μ˜ ν…ŒμŠ€νŠΈ 클래슀λ₯Ό λ§Œλ“€κ³  @Getter, @Setter 확인

둬볡을 ν™œμš©ν•œ μ˜μ‘΄κ΄€κ³„ μ£Όμž…

κΈ°λ³Έ μ½”λ“œ

// OrderServiceImpl.java

@Component
public class OrderServiceImpl implements OrderService {

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
}

둬볡 적용

// OrderServiceImpl.java

@Component
@RequiredArgsConstructor // final이 뢙은 μΈμŠ€ν„΄μŠ€μ— λŒ€ν•œ μƒμ„±μžλ₯Ό λ§Œλ“€μ–΄ μ€€λ‹€
public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    ...
}

βœ” @RequiredArgsConstructor : final이 뢙은 ν•„λ“œλ₯Ό λͺ¨μ•„μ„œ μƒμ„±μžλ₯Ό μžλ™μœΌλ‘œ λ§Œλ“€μ–΄μ€€λ‹€

μ΅œκ·Όμ—λŠ” μƒμ„±μžλ₯Ό 1개 두고 @Autowiredλ₯Ό μƒλž΅ν•˜λŠ” 방법을 주둜 μ‚¬μš©ν•˜λ©΄μ„œ, Lombok라이브러리의 @RequiredArgsConstructorλ₯Ό ν•¨κ»˜ μ‚¬μš©ν•œλ‹€

5. 쑰회 빈이 2개 이상일 λ•Œ

@AutowiredλŠ” νƒ€μž…μœΌλ‘œ μ‘°νšŒν•œλ‹€ (ac.getBean(DiscountPolicy.class)와 μœ μ‚¬) -> 같은 νƒ€μž…μ˜ 빈이 2개 이상이면 문제 λ°œμƒ!

μ˜ˆμ‹œ

// FixDiscountPolicy.java

@Component
public class FixDiscountPolicy implements DiscountPolicy {}
// RateDiscountPolicy.java

@Component
public class RateDiscountPolicy implements DiscountPolicy {}
// μ˜μ‘΄κ΄€κ²Œ μžλ™ μ£Όμž… μ‹€ν–‰

@Autowired
private DiscountPolicy discountPolicy
NoUniqueBeanDefinitionException: No qualifying bean of type 
'hello.core.discount.DiscountPolicy' available: 
expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy

NoUniqueBeanDefinitionException 였λ₯˜ λ°œμƒ

κ·Έλ ‡λ‹€κ³  ν•˜μœ„ νƒ€μž…μœΌλ‘œ μ§€μ •ν•˜λ©΄ DIP μœ„λ°° 및 μœ μ—°μ„± κ°μ†Œ! 그리고 ν•˜μœ„ νƒ€μž…λ„ κ°™μœΌλ©΄ 문제 λ°œμƒ κ°€λŠ₯

κ·Έλ ‡λ‹€λ©΄...?

6. @Autowired ν•„λ“œ λͺ…, @Qualifier, @Primary

쑰회 λŒ€μƒ 빈이 2개 이상일 λ•Œ ν•΄κ²° 방법

  1. @Autowired ν•„λ“œ λͺ… 맀칭
  2. @Qualifier -> @Qualifier끼리 맀칭 -> 빈 이름 맀칭
  3. @Primary μ‚¬μš©

1. @Autowired ν•„λ“œ λͺ… 맀칭

βœ” @Autowired λŠ” νƒ€μž… 맀칭을 μ‹œλ„ν•˜κ³ , μ΄λ•Œ μ—¬λŸ¬ 빈이 있으면 ν•„λ“œ 이름, νŒŒλΌλ―Έν„° μ΄λ¦„μœΌλ‘œ 빈 이름을 μΆ”κ°€ λ§€μΉ­ν•œλ‹€.

@Autowired
// κΈ°μ‘΄ μ½”λ“œ
// private DiscountPolicy discountPolicy
// ν•„λ“œ λͺ…을 빈 μ΄λ¦„μœΌλ‘œ λ³€κ²½
private DiscountPolicy rateDiscountPolicy 

2. @Qualifier μ‚¬μš©

βœ” @Qualifierλ₯Ό 톡해 μΆ”κ°€κ΅¬λΆ„μžλ₯Ό λΆ™μ—¬μ€€λ‹€ (빈 이름 λ³€κ²½ x)

빈 λ“±λ‘μ‹œ @Qualifier λΆ™μ—¬μ£ΌκΈ°


// RateDiscountPolicy.java
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}

// FixDiscountPolicy.java
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {}

μ£Όμž…μ‹œμ— @Qualifierλ₯Ό λΆ™μ—¬μ£Όκ³  λ“±λ‘ν•œ 이름을 적어주기

@Autowired
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy
discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}

ν•΄λ‹Ή qualifierλ₯Ό λͺ» 찾으면 λ‹€μ‹œ 빈 μ΄λ¦„μœΌλ‘œ 맀칭을 ν•˜μ§€λ§Œ qulifierλŠ” 가급적 qualifier끼리 λ§€μΉ­ν•˜λŠ” 것 ꢌμž₯!

3. @Primary μ‚¬μš©

βœ” @Primary: μš°μ„ μˆœμœ„ 지정

  • @Autowired μ‹œμ— μ—¬λŸ¬ 빈이 맀칭되면 @Primary κ°€ μš°μ„ κΆŒμ„ 가진닀
// rateDiscountPolicy κ°€ μš°μ„ κΆŒμ„ 가진닀

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}

@Component
public class FixDiscountPolicy implements DiscountPolicy {}

Primary vs Qualifier

@Qualifier 의 단점은 μ£Όμž… 받을 λ•Œ λͺ¨λ“  μ½”λ“œμ— @Qualifierλ₯Ό λΆ™μ—¬μ€˜μ•Ό ν•œλ‹€λŠ” 것

메인 컀λ„₯μ…˜μ€ @Primaryλ₯Ό ν™œμš©ν•΄ @Qualifier 지정 없이 νŽΈν•˜κ²Œ 쑰회

μ„œλΈŒ 컀λ„₯μ…˜μ€ @Qualifierλ₯Ό 지정해 λͺ…μ‹œμ μœΌλ‘œ 컀λ„₯μ…˜ 빈 νšλ“

μš°μ„ μˆœμœ„

쒁은 λ²”μœ„μ˜ @Qualifierκ°€ μš°μ„ κΆŒμ„ 가진닀

7. Annotation 직접 λ§Œλ“€κΈ°

@Qualifier("mainDiscountPolicy")와 같이 문자λ₯Ό 적으면 μ»΄νŒŒμΌμ‹œ νƒ€μž… 체크가 μ•ˆλœλ‹€

μ• λ…Έν…Œμ΄μ…˜μ„ λ§Œλ“€μ–΄μ„œ 문제 ν•΄κ²°

package hello.core.annotation;

import org.springframework.beans.factory.annotation.Qualifier;

import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Qualifier("mainDiscountPolicy")
public @interface MainDiscountPolicy {
}

annotation 적용

@Component
@MainDiscountPolicy
public class RateDiscountPolicy implements DiscountPolicy {}
// OrderServiceImpl.java

//μƒμ„±μž μžλ™ μ£Όμž…
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, @MainDiscountPolicy DiscountPolicy discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}

annotationμ—λŠ” 상속 κΈ°λŠ₯이 μ—†λ‹€

μœ„μ™€ 같이 μ—¬λŸ¬ anntotation을 λͺ¨μ•„μ„œ μ‚¬μš©ν•˜λŠ” κΈ°λŠ₯은 javaκ°€ μ•„λ‹ˆλΌ μŠ€ν”„λ§μ—μ„œ μ§€μ›ν•΄μ£ΌλŠ” κΈ°λŠ₯

λ‹€λ₯Έ annotation도 μ‘°ν•© / μž¬μ •μ˜ν•  수 μžˆμœΌλ‚˜ 가급적 지양

8. List, Map : μ‘°νšŒν•œ 빈이 λͺ¨λ‘ ν•„μš”ν•  λ•Œ

βœ” μ˜λ„μ μœΌλ‘œ ν•΄λ‹Ή νƒ€μž…μ˜ μŠ€ν”„λ§ 빈이 λͺ¨λ‘ ν•„μš”ν•œ 경우 -> List, Map ν™œμš©ν•΄ μ „λž΅νŒ¨ν„΄ κ΅¬ν˜„

ex) 할인 μ„œλΉ„μŠ€λ₯Ό μ œκ³΅ν•˜λŠ”λ° ν΄λΌμ΄μ–ΈνŠΈκ°€ 직접 ν• μΈμ˜ μ’…λ₯˜(rate, fix) 선택 κ°€λŠ₯

μ˜ˆμ‹œ μ½”λ“œ


package hello.core.autowired;

import hello.core.AutoAppConfig;
import hello.core.discount.DiscountPolicy;
import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.scan.AutoAppConfigTest;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

public class allBeanTest {

    @Test
    void findAllBean() {
        AnnotationConfigApplicationContext 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, "fixDiscountPolicy");

        Assertions.assertThat(discountService).isInstanceOf(DiscountService.class);
        Assertions.assertThat(discountPrice).isEqualTo(1000);

        int rateDiscountPrice = discountService.discount(member, 20000, "rateDiscountPolicy");
        Assertions.assertThat(rateDiscountPrice).isEqualTo(2000);


    }

    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);
        }
    }
}

둜직

DiscountServiceλŠ” Map으둜 λͺ¨λ“  DiscoutPolicy μ£Όμž… λ°›λŠ”λ‹€ (fixDiscountPolicy & rateDiscountPolicy)

λ©”μ„œλ“œ discount()λŠ” doscountCode둜 λ„˜μ–΄μ˜¨ discountPolicy에 λ§žλŠ” μŠ€ν”„λ§ λΉˆμ„ μ°Ύμ•„μ„œ μ‹€ν–‰ν•œλ‹€

μ£Όμž…

Map<String, DiscountPolicy> : 킀에 μŠ€ν”„λ§ 빈의 이름을, κ°’μœΌλ‘œ DiscountPolicy νƒ€μž…μœΌλ‘œ μ‘°νšŒν•œ λͺ¨λ“  μŠ€ν”„λ§ λΉˆμ„ λ‹΄μ•„μ€€λ‹€.

List<DiscountPolicy> : DiscountPolicy νƒ€μž…μœΌλ‘œ μ‘°νšŒν•œ λͺ¨λ“  μŠ€ν”„λ§ λΉˆμ„ λ‹΄μ•„μ€€λ‹€.

λ§Œμ•½ ν•΄λ‹Ήν•˜λŠ” νƒ€μž…μ˜ μŠ€ν”„λ§ 빈이 μ—†μœΌλ©΄, 빈 μ»¬λ ‰μ…˜μ΄λ‚˜ Map을 μ£Όμž…

9. μžλ™, μˆ˜λ™μ˜ μ˜¬λ°”λ₯Έ 싀무 운영 κΈ°μ€€

κΈ°λ³ΈμœΌλ‘œλŠ” νŽΈλ¦¬ν•œ μžλ™ κΈ°λŠ₯ μ‚¬μš©

μŠ€ν”„λ§μ΄ λ‚˜μ˜€κ³  μ‹œκ°„μ΄ 지날 수둝 μžλ™ μ„ ν˜Έ μΆ”μ„Έ

@Component 뿐만 μ•„λ‹ˆλΌ @Controller, @Service , @Repository 처럼 계측에 λ§žμΆ”μ–΄ 일반적인 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‘œμ§μ„ μžλ™μœΌλ‘œ μŠ€μΊ”ν•  수 μžˆλ„λ‘ 지원

μŠ€ν”„λ§λΆ€νŠΈλŠ” μ»΄ν¬λ„ŒνŠΈ μŠ€μΊ”μ„ 기본으둜 μ‚¬μš©ν•˜κ³  λ‹€λ₯Έ μŠ€ν”„λ§ λΉˆλ“€λ„ 쑰건이 맞으면 μžλ™μœΌλ‘œ 동λ₯΅λ˜λ„둝 섀계

μˆ˜λ™ 빈 등둝은 λ‘œμ§μ— 따라 μ‚¬μš©

βœ” 업무 둜직 빈

  • 웹을 μ§€μ›ν•˜λŠ” 컨트둀러, 핡심 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직이 μžˆλŠ” μ„œλΉ„μŠ€, 데이터 κ³„μΈ΅μ˜ λ‘œμ§μ„ μ²˜λ¦¬ν•˜λŠ” 리포지토리 λ“±
  • 보톡 λΉ„μ¦ˆλ‹ˆμŠ€ μš”κ΅¬μ‚¬ν•­μ„ κ°œλ°œν•  λ•Œ μΆ”κ°€λ˜κ±°λ‚˜ λ³€κ²½

βœ” 기술 지원 빈

  • 기술적인 λ¬Έμ œλ‚˜ 곡톡 관심사(AOP)λ₯Ό μ²˜λ¦¬ν•  λ•Œ 주둜 μ‚¬μš©
  • λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²°μ΄λ‚˜,곡톡 둜그 처리처럼 업무 λ‘œμ§μ„ μ§€μ›ν•˜κΈ° μœ„ν•œ ν•˜λΆ€ κΈ°μˆ μ΄λ‚˜ 곡톡 기술 λ“±

업무 λ‘œμ§μ€ μˆ«μžλ„ 맀우 많고 ν•œλ²ˆ κ°œλ°œν•˜λ©΄ 컨트둀러, μ„œλΉ„μŠ€, 리포지토리 λ“± μœ μ‚¬ν•œ νŒ¨ν„΄ 쑴재
-> μžλ™ κΈ°λŠ₯ μ‚¬μš©

기술 지원 λ‘œμ§μ€ μˆ˜κ°€ μƒλŒ€μ μœΌλ‘œ 적고, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „λ°˜μ— 걸쳐 κ΄‘λ²”μœ„ν•˜κ²Œ 영ν–₯을 미치고, 문제 λ°œμƒ μ‹œ 디버깅 어렀움
-> μˆ˜λ™ 빈 등둝 μ‚¬μš©

βœ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— κ΄‘λ²”μœ„ν•˜κ²Œ 영ν–₯을 λ―ΈμΉ˜λŠ” 기술 지원 κ°μ²΄λŠ” μˆ˜λ™ 빈으둜 λ“±λ‘ν•΄μ„œ μ„€μ • 정보에 λ°”λ‘œ λ‚˜νƒ€λ‚˜κ²Œ ν•˜λŠ” 것이 μœ μ§€λ³΄μˆ˜ ν•˜κΈ° μ’‹λ‹€

λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 μ€‘μ—μ„œ λ‹€ν˜•μ„±μ„ 적극 ν™œμš©ν•  λ•Œ

μœ„μ˜ List, Mapκ³Ό 같이 λ‹€ν˜•μ„±μ„ 적극 ν™œμš©ν•˜λŠ” 경우 ν˜‘μ—… μ‹œμ— λ‹€λ₯Έ κ°œλ°œμžκ°€ μ½”λ“œλ₯Ό νŒŒμ•…ν•˜κΈ° μ–΄λ ΅λ‹€

βœ” μˆ˜λ™ 빈으둜 λ“±λ‘ν•˜κ±°λ‚˜ μžλ™μœΌλ‘œ ν•˜λ©΄ νŠΉμ • νŒ¨ν‚€μ§€μ— 같이 묢어두기

μ˜ˆμ‹œ μ½”λ“œ

@Configuration
public class DiscountPolicyConfig {

    @Bean
    public DiscountPolicy rateDiscountPolicy() {
        return new RateDiscountPolicy();
    }

    @Bean
    public DiscountPolicy fixDiscountPolicy() {
        return new FixDiscountPolicy();
    }
}

μ„€μ • 정보와 μ˜μ‘΄κ΄€κ³„ μ£Όμž… 정보가 ν•œ λˆˆμ— νŒŒμ•…λœλ‹€

λŒ“κΈ€