본문 바로가기
트러블슈팅과 고민/고민

DI, IoC, AOP에 관한 고민

by 정재익 2026. 3. 15.

책이나 인터넷 강의에서는 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("나", "하이");
    }
}