Spring

[Spring] IoC(Inversion of Control)

leevigong 2025. 12. 31. 19:00
반응형

IoC(Inversion of Control): 제어의 역전

평소에 우리는 객체가 필요하면 직접 생성(new)합니다

public class UserService {
    private UserRepository repository = new UserRepository();
    
    public User findUser(Long id) {
        return repository.findById(id);
    }
}

즉, 객체를 내가 만들고, 내가 관리했습니다

근데 이렇게 하면 문제가 있습니다

  • UserRepository를 다른 구현체로 바꾸려면 UserService 코드를 수정해야 한다
  • 테스트할 때 Mock 객체로 바꿀 수가 없다
  • UserService가 UserRepository의 구체적인 생성 방법을 알아야 한다

Spring의 해결 방법

Spring은 객체 생성 권한을 가져가

@Service
public class UserService {
    private final UserRepository repository;
    
    public UserService(UserRepository repository) {
        this.repository = repository;
    }
}

@Repository
public class UserRepository {
    public User findById(Long id) {
        // DB 조회
    }
}

@Service, @Repository 붙여놓으면 Spring이 알아서 객체를 만듭니다. 이게 IoC (Inversion of Control) 제어의 역전입니다

IoC 컨테이너

Spring이 객체를 만들고 관리하는 곳을 IoC 컨테이너라고 합니다. 정확히는 ApplicationContext

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Application.class, args);
        
        // Spring이 만든 객체 가져오기
        UserService userService = context.getBean(UserService.class);
    }
}

컨테이너가 관리하는 객체를 Bean이라고 부릅니다

Bean으로 등록하는 방법

1. 컴포넌트 스캔

@Component  // 또는 @Service, @Repository, @Controller
public class UserService {
}

@Component 붙이면 Spring이 자동으로 찾아서 Bean으로 등록합니다

 

2. @Bean 메서드

@Configuration
public class AppConfig {
    
    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }
}

직접 Bean을 정의할 수도 있습니다

IoC의 장점

  1. 결합도 감소: UserService는 UserRepository 인터페이스만 알면 된다
  2. 테스트 용이: Mock 객체로 쉽게 교체 가능
  3. 객체 재사용: Singleton으로 관리되어 메모리 효율적
  4. 설정 중앙화: 객체 생성 로직을 한 곳에서 관리

IoC의 구현 방법

1. DI (Dependency Injection) - Spring이 선택한 방식 (자세한 내용은 다음 글에서..~)

public UserService(UserRepository repository) {
    this.repository = repository;
}

 

2. Service Locator

UserRepository repo = ServiceLocator.get(UserRepository.class);

 

3. Factory Pattern

UserRepository repo = RepositoryFactory.create();

 

정리

  • IoC: 객체 생성 제어권을 Spring에게 넘긴다
  • IoC 컨테이너: Spring이 Bean을 관리하는 곳 (ApplicationContext)
  • Bean: Spring이 관리하는 객체
  • 등록 방법: @Component 또는 @Bean
  • 구현 방법: DI, Service Locator, Factory 등 (Spring은 DI를 사용)
반응형