Bean에 대한 설명은 어제 작성했던 IoC/DI의 설명에서 이어진다.
IoC는 개발자가 생성하는 객체를 스프링에서 대신 생성해 주는 것이다.
여기서, 스프링이 관리하는 객체를 바로 Bean이라고 한다.
또한, 이 Bean의 집합 즉 Bean을 모아두고 있는 상자를 바로 IoC Container라고 한다.
Bean은 애플리케이션 전역에서 사용 가능하며, Spring 컨테이너에 의하여 생성, 관리 및 소멸된다.
또한, 기본적으로 싱글톤 스코프로 관리된다.
싱글톤(Singleton)은 클래스 내에 인스턴스가 1개만 생성되는 디자인 패턴이다.
이와 같은 패턴을 사용하는 이유는, 인스턴스(객체)를 딱 1개만 생성하기 때문에 메모리의 낭비를 방지하며, 전반적인 시스템의 설정이나 자원등을 관리할 때, 데이터의 일관성을 유지할 수 있는 장점이 있다.
@Service
public class UserService {
private final UserRepository userRepository = new UserRepository(...);
}
Spring에서 객체를 생성할때는 위의 코드와 같이new키워드를 사용하여 객체를 생성해주어야 한다.
하지만, 스프링의 IoC/DI개념을 사용하면
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
}
이렇게 new키워드를 사용하지 않아도 객체를 생성할 수 있게 된다.
이게 가능한 이유는, 스프링이 직접 IoC컨테이너로부터 Bean(객체)를 관리하여 DI(의존성주입)을 하기 때문이다.
그렇다면, IoC/DI는 언제 사용하는것이 좋을까?
// ✅ Spring Bean으로 관리
@Service
public class UserService { } // 비즈니스 로직
@Repository
public class UserRepository { } // 데이터 접근
@Component
public class EmailSender { } // 인프라
@Controller
public class UserController { } // 컨트롤러
IoC/DI는 애플리케이션의 기능을 수행하는 객체를 관리할 때 사용한다.
이런 객체는 여러 곳에서 재사용되거나, 객체간의 의존 관계를 Spring이 관리해주기 때문에 유지보수가 쉽다.
하지만,
public class User{
private String name;
private int age;
}
와 같이 요청마다 새로운 데이터가 담기는 이러한 객체의 경우엔 IoC/DI를 사용하지 않는다.
스프링에서 Bean을 등록하는 방법은 자동 등록과 수동 등록이 있다.
Spring이 Bean을 자동 등록 하는 방법은 @Component 클래스를 찾아서 Bean으로 등록하는 것이다.
코드를 작성하기 이전에
@Component
public @interface Service{
}
와 같이 선언해주면 된다.
또한, @ComponentScan 어노테이션을 사용하여, 컨테이너가 빈으로 사용할 클래스를 찾을 수 있게 알려주는 안내자 역할을 한다.
보통은 @SpringBootApplication 어노테이션 안에 포함되어 있어서 신경쓸 이유는 없다.
Spring의 @Configuration과 @Bean을 사용하여 수동으로 등록해줄 수 있다.
@Configuration
public class AppConfig {
@Bean(name="커스텀 빈 이름")
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
기본적으로는 자동 등록을 하기 때문에, 굳이 수동 등록을 할 필요는 없다.
하지만, 외부라이브러리를 Bean으로 등록하고 싶다면 외부 라이브러리의 내부 코드를 수정(@Component와 같은 어노테이션)할 수 없기 때문에 직접 등록 해줘야 한다.