책이나 인터넷 강의에서는 DI, IoC, AOP에 대해서 잘 알려주지만 많이 들어도 역시나 모호한 면이 있다.
그것은 직접 코드가 물리적으로 돌아가는 것을 보지 못해서인것같다.
그동안 고민도 많이하고 자바로 스프링도 조금씩 만들고 있는데 내 나름대로의 결론이다. 아직까지 부족한 면이 있을것이다.
DI
1. IoC를 구현하는 방법중하나
2. 프록시빈을 주입할 수 있어 AOP를 가능하게한다.
3. 개발자가 하나하나 팩토리를 작성할 필요 없음
4. 외부에서의 구현체 주입으로 구현체 변경에도 수정이 일어나지 않아 결합도 하락 (구현체가 여러개일때 프라이머리)
IoC
1. 객체의 생성, 생명주기, 메소드의 실행 흐름등을 외부로 위임
2. 객체를 생성하지 않아 결합도 하락 (new 연산자의 외부 이동) (DI가 없으면 구현체 변경시 수정 발생)
3. 이벤트와 리스너를 미리 매핑시킴으로서 실행 흐름의 위임 및 결합도하락
AOP
1. 부가기능의 모듈화
2. 동적프록시를 통한 부가기능 주입
3. DI의 힘을 빌려 데코레이터 패턴 구현
IoC가 없을 때
@Getter
public class Memo {
private String author;
private String content;
public Memo(String author, String content) {
this.author = author;
this.content = content;
}
}
public class MemoService {
private final MemoRepository memoRepository;
public MemoService(MemoRepository memoRepository) {
this.memoRepository = memoRepository;
}
public void create(String author, String content) {
Memo memo = new Memo(author, content);
memoRepository.add(memo);
}
}
public interface MemoRepository {
void add(Memo memo);
}
public class MemoList implements MemoRepository{
private List<Memo> memoList = new ArrayList<>();
@Override
public void add(Memo memo) {
memoList.add(memo);
}
}
public class MemoMap implements MemoRepository{
private Map<String, String> memoMap = new HashMap<>();
@Override
public void add(Memo memo) {
memoMap.put(memo.getAuthor(), memo.getContent());
}
}
public class MemoMainV1 {
public static void main(String[] args) {
// 제어의 역전 적용 X
// 직접 객체를 생성하고 구체클래스를 알아야한다. 또한 구체클래스의 변경이 일어날때마다 주석을 풀어야 한다.
MemoRepository memoList = new MemoList();
MemoService listService = new MemoService(memoList);
listService.create("나", "하이");
// MemoRepository memoMap = new MemoMap();
// MemoService mapService = new MemoService(memoMap);
// mapService.create("나", "하이");
}
}
IoC 적용
public class MemoServiceFactory {
public static MemoService createMemoList() {
return new MemoService(new MemoList());
}
public static MemoService createMemoMap() {
return new MemoService(new MemoMap());
}
}
public class MemoMainV2 {
public static void main(String[] args) {
// 제어의 역전 적용
// 직접 객체를 생성하지 않아도 된다. 다만 구체클래스의 변경이 일어나면 주석을 풀어야한다.
// DI를 적용하게되면 의존관계 주입때 구현체를 주입해주기때문에 주석을 둘 필요없이 하나의 메서드만 있으면된다.
// 구현체가 여러개라면 프라이어티로 주입해준다. 구현체마다 팩토리메서드를 만들 필요가 없다.
MemoService listService = MemoServiceFactory.createMemoList();
listService.create("나", "하이");
// MemoService mapService = MemoServiceFactory.createMemoMap();
// mapService.create("나", "하이");
}
}
'트러블슈팅과 고민 > 고민' 카테고리의 다른 글
| 실시간 인기글의 캐시 갱신시 빈 페이지 반환에 대한 개선 (스케줄러, 캐시어사이드 동시 사용) (0) | 2026.01.27 |
|---|---|
| 소셜 로그인/회원가입 반환 프로토콜 재설계 (0) | 2025.10.03 |
| 헥사고날 아키텍처에서 신고(Report) 엔티티의 도메인 위치 딜레마 (1) | 2025.09.05 |
| DTO와 의존성, 계층의 분리에 대한 고민 (3) | 2025.08.15 |
| 모놀리식 -> 헥사고날 전환 도메인 경계 문제 해결 (0) | 2025.08.12 |