🌱 μŠ€ν”„λ§μ˜ DI 방법 (μƒμ„±μž μ£Όμž… VS ν•„λ“œ μ£Όμž…)


μŠ€ν”„λ§μ˜ DI 방법

DI

  • 변경에 μ˜ν•΄ 영ν–₯을 λ°›λŠ” 관계

1. μƒμ„±μž μ£Όμž…(Constructor Injection)

@Service
public class StationConstructorService {
    private StationRepository stationRepository;

    public StationConstructorService(StationRepository stationRepository) {
        this.stationRepository = stationRepository;
    }

    public String sayHi() {
        return stationRepository.sayHi();
    }
}

μŠ€ν”„λ§ 4.3 λΆ€ν„°λŠ” 단일 μƒμ„±μžμΈ 경우 μƒμ„±μžμ— @Authowiredλ₯Ό 뢙이지 μ•Šμ•„λ„ λœλ‹€.

2. ν•„λ“œ μ£Όμž…(Field Injection)

@Service
public class StationFieldService {
    @Autowired
    private StationRepository stationRepository;

    public String sayHi() {
        return stationRepository.sayHi();
    }
}

ν•„λ“œμ— @Autowired μ–΄λ…Έν…Œμ΄μ…˜μ„ λΆ™μ—¬μ€€λ‹€.

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

@Service
public class StationSetterService {
    private StationRepository stationRepository;

    public String sayHi() {
        return stationRepository.sayHi();
    }

    @Autowired
    public void setStationRepository(StationRepository stationRepository) {
        this.stationRepository = stationRepository;
    }
}

setterλ₯Ό 톡해 μ˜μ‘΄μ„±μ„ μ£Όμž…ν•˜λŠ” λ°©λ²•μœΌλ‘œ setter에 @Autowired μ–΄λ…Έν…Œμ΄μ…˜μ„ λΆ™μ—¬μ€€λ‹€.

ν•„λ“œ μ£Όμž…λŒ€μ‹  μƒμ„±μž μ£Όμž…μ„ κΆŒκ³ ν•˜λŠ” 이유

μΈν…”λ¦¬μ œμ΄μ—μ„œ ν•„λ“œ μ£Όμž…μ„ μ‚¬μš©ν•  경우 μƒμ„±μž μ£Όμž…μœΌλ‘œ λ³€κ²½ν•  것을 κΆŒκ³ ν•œλ‹€.
κ·Έ μ΄μœ λŠ” λ¬΄μ—‡μΌκΉŒ?

μˆœν™˜ μ°Έμ‘°λ₯Ό 방지할 수 μžˆλ‹€.

극단적인 예둜 객체 Aκ°€ 객체 Bλ₯Ό μ°Έμ‘°ν•˜κ³ , λ‹€μ‹œ 객체 Bκ°€ 객체 Aλ₯Ό μ°Έμ‘°ν•œλ‹€κ³  ν•˜μž.

λ¨Όμ € ν•„λ“œ μ£Όμž…μ˜ 경우 μˆœν™˜ μ°Έμ‘°μ—μ„œ μ–΄λ–€ 문제λ₯Ό μΌμœΌν‚€λŠ”μ§€ 보겠닀.

@FunctionalInterface
public interface GameService {
    void gameMethod();
}
@Service
public class GameServiceImpl implements GameService {
    @Autowired
    private PieceService pieceService;

    @Override
    public void gameMethod() {
        pieceService.pieceMethod();
    }
}
@FunctionalInterface
public interface PieceService {
    void pieceMethod();
}
@Service
public class PieceServiceImpl implements PieceService {
    @Autowired
    private GameServiceImpl gameServiceImpl;

    @Override
    public void pieceMethod() {
        gameServiceImpl.gameMethod();
    }
}

ν…ŒμŠ€νŠΈ

μœ„μ™€ 같이 κ°„λ‹¨ν•œ ν…ŒμŠ€λ₯Ό ν•΄λ³΄μ•˜μ„ λ•Œ, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ꡬ동은 잘 λ˜μ§€λ§Œ μ„œλ‘œμ˜ λ©”μ†Œλ“œλ₯Ό κ³„μ†ν•΄μ„œ ν˜ΈμΆœν•˜κ³  있기 λ•Œλ¬Έμ— StackOverflowError κ°€ λ°œμƒν•œλ‹€.
μ–΄μ¨Œλ“  μˆœν™˜ μ°Έμ‘°κ°€ μΌμ–΄λ‚¬μŒμ—λ„ μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆκ°€ λ™μž‘ν•˜λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μžμ²΄λŠ” λ¬Έμ œμ—†μ΄ κ΅¬λ™λœλ‹€.

κ·Έλ ‡λ‹€λ©΄ μƒμ„±μž μ£Όμž…μ˜ κ²½μš°λŠ” μ–΄λ– ν• κΉŒ?

@Service
public class GameServiceImpl implements GameService {
    private final PieceServiceImpl pieceService;

    public GameServiceImpl(PieceServiceImpl pieceService) {
        this.pieceService = pieceService;
    }

    @Override
    public void gameMethod() {
        pieceService.pieceMethod();
    }
}
@Service
public class PieceServiceImpl implements PieceService {
    private final GameServiceImpl gameServiceImpl;

    public PieceServiceImpl(GameServiceImpl gameServiceImpl) {
        this.gameServiceImpl = gameServiceImpl;
    }

    @Override
    public void pieceMethod() {
        gameServiceImpl.gameMethod();
    }
}

둜그둜 μˆœν™˜μ°Έμ‘°κ°€ μΌμ–΄λ‚˜κ³  μžˆμŒμ„ λ³΄μ—¬μ£Όλ©΄μ„œ μ»¨ν…Œμ΄λ„ˆκ°€ λΉˆλ“€μ„ λ“±λ‘ν•˜μ§€λ„ λͺ»ν•œμ±„, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ꡬ동 μžμ²΄λ„ μ‹€νŒ¨ν•˜μ˜€λ‹€.

μ—¬κΈ°μ„œ 이런 차이점을 λ³΄μ΄λŠ” μ΄μœ λŠ” ν•„λ“œ μ£Όμž…κ³Ό μƒμ„±μž μ£Όμž…μ€ λΉˆμ„ μ£Όμž…ν•˜λŠ” μˆœμ„œμ— 차이가 있기 λ•Œλ¬Έμ΄λ‹€.

ν•„λ“œ μ£Όμž…μ€ λΉˆμ„ 생성 ν›„ μ–΄λ…Έν…Œμ΄μ…˜μ΄ 뢙은 ν•„λ“œμ— ν•΄λ‹Ήν•˜λŠ” λΉˆμ„ μ°Ύμ•„μ„œ μ£Όμž…ν•œλ‹€.
빈 생성이 λ¨Όμ € μΌμ–΄λ‚˜κ³ , ν•„λ“œμ— λŒ€ν•œ μ£Όμž…μ„ μˆ˜ν–‰ν•˜λŠ” 것이닀.

μƒμ„±μž μ£Όμž…μ€ μƒμ„±μžλ‘œ 객체λ₯Ό μƒμ„±ν•˜λŠ” μ‹œμ μ— ν•„μš”ν•œ λΉˆμ„ μ£Όμž…ν•œλ‹€.
λ¨Όμ € λΉˆμ„ μƒμ„±ν•˜μ§€ μ•Šκ³ , μƒμ„±μžμ˜ μΈμžμ— μ‚¬μš©λ˜λŠ” λΉˆμ„ μ°Ύκ±°λ‚˜ 빈 νŒ©ν„°λ¦¬μ—μ„œ λ§Œλ“œλŠ” μˆœμ„œμ΄λ‹€.

λ•Œλ¬Έμ— 객체 생성 μ‹œμ μ— λΉˆμ„ μ£Όμž…ν•˜λŠ” μƒμ„±μž μ£Όμž…μ€ μˆœν™˜ 참쑰에 λŒ€ν•œ 였λ₯˜λ₯Ό κ²ͺ을 수 μžˆλ‹€.
μˆœν™˜λœ μ°Έμ‘° 관계λ₯Ό κ°€μ§€λŠ” 객체듀이 μƒμ„±λ˜μ§€ μ•Šμ€ μ‹œμ μ—μ„œ λΉˆμ„ μ°Έμ‘°ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.
μ΄λ ‡κ²Œ 보면 μ–΄μ°Œλλ“  μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ ꡬ동 μ‹œν‚€λŠ” ν•„λ“œ μ£Όμž…μ΄ 더 μ’‹λ‹€κ³  생각할 수 μžˆλ‹€.

ν•˜μ§€λ§Œ 객체의 μˆœν™˜ μ°Έμ‘°κ°€ μΌμ–΄λ‚œλ‹€λŠ” 것은 μ• μ΄ˆμ— 잘λͺ»λœ 섀계라고 ν•  수 μžˆλ‹€.
λ•Œλ¬Έμ— 였히렀 μƒμ„±μž μ£Όμž…μ„ μ‚¬μš©ν•˜μ—¬ μˆœν™˜ μ°Έμ‘°κ°€ λ˜λŠ” 섀계λ₯Ό 막을 수 μžˆλ„λ‘ ν•˜μž.

Immutable

ν•„λ“œ μ£Όμž…κ³Ό μˆ˜μ •μž μ£Όμž…μ€ ν•΄λ‹Ή ν•„λ“œλ₯Ό final둜 μ„ μ–Έν•  수 μ—†λ‹€.
즉 κ°€λ³€ 객체둜만 μ‚¬μš©μ΄ κ°€λŠ₯ν•œ 것이닀.

ν•˜μ§€λ§Œ μƒμ„±μž μ£Όμž…μ€ ν•„λ“œλ₯Ό final둜 μ„ μ–Έν•  수 μžˆλ‹€.
이둜 인해 κ°€λ³€ 객체둜 인해 λ°œμƒν•  수 μžˆλŠ” 였λ₯˜λ₯Ό 사전에 λ§‰λŠ”λ‹€.


μ°Έκ³ 

μŠ€ν”„λ§ - μƒμ„±μž μ£Όμž…μ„ μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” 이유, ν•„λ“œμΈμ μ…˜μ΄ 쒋지 μ•Šμ€ 이μœ