오늘은 Spring IoC 컨테이너와 Bean에 대해 학습했다. Spring IoC는 객체의 생성을 관리하고 의존성을 주입하는 중요한 개념이며, 이를 통해 코드의 유지보수성과 유연성이 크게 향상된다.
이전에 학습한 DI(Dependency Injection)를 사용하기 위해서는 객체가 먼저 생성되어야 한다. 이때, 객체를 언제, 어디서, 누가 생성하고 관리할 것인지가 중요한데, 이 역할을 Spring IoC 컨테이너가 맡는다.
Spring에서 Bean을 등록하는 방법은 여러 가지가 있다. 그중 가장 기본적인 방법은 @Component 어노테이션을 사용하는 것이다.
@Component는 클래스를 Bean으로 등록하기 위해 사용된다. Spring 서버가 시작될 때, IoC 컨테이너에 해당 클래스를 Bean으로 저장한다.
@Component
public class MemoService { ... }
이 코드에서 MemoService는 Spring IoC 컨테이너에 memoService라는 이름으로 저장되며, 관리된다.
@ComponentScan을 사용하면 특정 패키지와 그 하위 패키지에 있는 모든 @Component 클래스를 스캔하여 Bean으로 등록할 수 있다.
@Configuration
@ComponentScan(basePackages = "com.sparta.memo")
class BeanConfig { ... }
Spring Boot에서는 @SpringBootApplication에 기본적으로 @ComponentScan이 설정되어 있기 때문에 따로 설정하지 않아도 된다.
Spring IoC 컨테이너에 등록된 Bean을 사용하는 방법은 @Autowired 어노테이션을 통해 의존성을 주입하는 것이다.
@Component
public class MemoService {
@Autowired
private MemoRepository memoRepository;
}
@Component
public class MemoService {
private final MemoRepository memoRepository;
@Autowired
public MemoService(MemoRepository memoRepository) {
this.memoRepository = memoRepository;
}
}
생성자 주입 방식은 객체의 불변성을 확보할 수 있어, 더 많이 사용된다.
때로는 IoC 컨테이너에서 수동으로 Bean을 가져와야 할 때가 있다. 이때 ApplicationContext를 사용할 수 있다.
@Component
public class MemoService {
private final MemoRepository memoRepository;
public MemoService(ApplicationContext context) {
this.memoRepository = context.getBean(MemoRepository.class);
}
}
ApplicationContext는 Spring의 BeanFactory를 상속받아 확장된 기능을 제공하는 IoC 컨테이너다. 이를 통해 Bean을 직접 가져와 사용할 수 있다.
Spring에서는 3 Layer Annotation을 사용하여, 각 클래스의 역할을 명확히 하고 Bean으로 등록할 수 있다.
이 어노테이션들은 모두 @Component를 포함하고 있기 때문에, 따로 @Component를 선언할 필요 없이 Bean으로 등록된다.
IoC 컨테이너와 Bean의 개념을 통해, Spring이 어떻게 객체의 생성을 관리하고 의존성을 주입하는지를 이해할 수 있었다. 이를 통해 코드의 유연성과 유지보수성이 크게 향상되며, 특히 @Autowired와 ApplicationContext를 활용하여 객체를 주입받고 사용하는 방식이 편리하다는 것을 느꼈다. 앞으로는 3 Layer Annotation을 활용하여 더 명확한 구조를 설계할 수 있을 것 같다.