개발지식

[SPRING] IOC(Inversion of Control) 제어의 역전

우루쾅 2024. 2. 5. 18:21
728x90
반응형
SMALL

IOC 제어의 역전

프레임워크가 내 코드를 대신 호출해 주는 것, 말 그대로 제어권이 뒤바뀌는 것을 제어의 역전이라고 합니다.

 

기존 프로그램은 클라이언트 구현 객체가 스스로 필요한 서버 구현 객체를 생성하고, 연결하고, 실행했습니다.

한마디로 구현 객체가 프로그램의 제어 흐름을 스스로 조종했으며 개발자 입장에서는 자연스러운 흐름이였습니다.

 

하지만 IOC(Inversion of Control)는 일반적인 객체의 생명주기를 개발자가 직접 관리하는 것이 아닌,

스프링 프레임워크가 객체의 생성과 관리와 같은 프로그램의 제어 흐름을 관리하는 것을 제어의 역전(IOC)이라 합니다.

 

프레임워크 VS 라이브러리

● 프레임워크가 내가 작성한 코드를 제어하고, 대신 실행하면 그것은 프레임워크가 맞다

● 반면에 내가 작성한 코드가 직접 제어의 흐름을 담당한다면 그것은 프레임워크가 아닌 라이브러리다.

 


스프링 IOC를 코드 예시를 통해 확인을 해보자!

// UserService 인터페이스
public interface UserService {
    void addUser(User user);
}

// UserService 구현 클래스
public class UserServiceImpl implements UserService {
    private UserRepository userRepository;
    
    public UserServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public void addUser(User user) {
        userRepository.save(user);
    }
}

// UserRepository 인터페이스
public interface UserRepository {
    void save(User user);
}

// UserRepository 구현 클래스
public class UserRepositoryImpl implements UserRepository {
    public void save(User user) {
        // 사용자 정보를 저장하는 로직
    }
}

 

위 코드에서 UserServiceImpl 클래스가 UserRepositoryImpl 클래스에 의존하고 있습니다.

일반적으로 이러한 의존성은 개발자가 직접 객체를 생성하고 관리를 해야 하는데,

스프링 프레임워크를 사용하면 IOC 컨테이너에게 객체의 생성과 관리를 맡길 수 있습니다.

 

아래는 스프링을 사용하여 객체를 생성하고 의존성을 주입하는 예시입니다!

 

// 스프링 설정 파일 (applicationContext.xml 또는 Java Config)
@Configuration
public class AppConfig {
    @Bean
    public UserService userService(UserRepository userRepository) {
        return new UserServiceImpl(userRepository);
    }
    
    @Bean
    public UserRepository userRepository() {
        return new UserRepositoryImpl();
    }
}

// 메인 애플리케이션 클래스
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        
        UserService userService = context.getBean(UserService.class);
        
        User user = new User("John Doe");
        userService.addUser(user);
    }
}

 

위 코드에서 AppConfig 클래스는 스프링 설정 파일로 사용합니다.

@Configuration 어노테이션을 통해 스프링이 해당 클래스를 설정 파일로 인식하게 됩니다.

 

@Configuration 어노테이션 아래의 @Bean 어노테이션들은 스프링 컨테이너에게 해당 빈(Bean) 객체의 생성을 맡깁니다.

UserServiceImpl 객체와 UserRepositoryImpl 객체가 각각 빈으로 등록되며,

UserRepositoryImpl 객체는 UserServiceImpl 객체에 의존성 주입(Dependency Injection)이 됩니다.

 

메인 애플리케이션 클래스에서는 ApplicationContext를 통해 스프링 컨테이너를 생성하고,

getBean() 메서드를 사용하여 UserService 빈 객체를 가져옵니다.

이후 스프링은 UserServiceImpl 객체를 생성하면서 UserRepositoryImpl 객체를 주입하여 의존성을 해결합니다!

 

이렇게 스프링의 IOC를 사용하면 개발자는 객체의 생성과 의존성 주입을 직접 관리하지 않아도 되며, 스프링 컨테이너가 객체의 생명주기를 관리하므로 개발자는 비즈니스 로직에 집중할 수 있습니다.

 

 

● IOC 컨테이너

IOC 컨테이너는 IOC 개념을 구현한 프레임워크나 라이브러리로, 객체의 생성과 관리, 의존성 주입 등을 담당합니다.

주로 응용 프로그램의 구성 요소들을 생성하고 조립하는 역할을 수행하며, 개발자가 직접 객체를 생성하고 의존성을 관리하는 번거로움을 줄여줍니다.

 

즉, IOC 는 개념이며, IOC 컨테이너는 이 개념을 구현한 도구입니다.

IOC 는 개념적인 측면을 나타내는 반면, IOC 컨테이너는 실제 IOC를 구현한 도구로서 개발자가 객체의 생명 주기와 의존성 관리를 위임할 수 있는 환경을 제공합니다.

 

 

한줄로 간단하게 정리하자면 

스프링 프레임워크에서 객체의 생성과 의존성 주입을 담당하는 것, 이것이 IOC(제어의 역전)의 개념이다!

 

 

 

 

출처

인프런 - 김영한의 스프링 핵심원리 - 기본편 (IoC, DI, 그리고 컨테이너)

GPT-4(갓피티..)

728x90
반응형
LIST