Spring Bean은 Spring IoC(Inversion of Control) 컨테이너에서 관리하는 객체를 의미한다.
Spring Framework의 핵심 개념 중 하나로, Spring 컨테이너에 의해 인스턴스화, 조립, 관리되는 객체다. 특정 클래스에 종속적이지 않아, 코드의 유연성을 높이고 테스트를 용이하게 한다.
Spring Bean의 주요 특징은 다음과 같다:
기본적으로 Spring Bean은 Singleton Scope를 가진다. Spring 컨테이너 내에서 각 빈은 하나의 인스턴스만 존재하게 된다.
Spring Bean은 초기화 및 소멸 과정에서 특정 동작을 수행할 수 있다. InitializingBean 및 DisposableBean 인터페이스를 구현하거나, @PostConstruct 및 @PreDestroy 어노테이션을 사용하여 이러한 콜백을 정의할 수 있다.
Spring Bean은 Dependency Injection(DI)을 통해 다른 Bean에 의존성을 주입할 수 있다. 이는 객체 간의 독립성을 유지시켜 코드의 재사용성 및 유지보수성을 높인다.
아래와 같은 컨트롤러가 있을 때,
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired //-> 주입된 서비스를 자동으로 가져다가 연결
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
@Controller, @Service, @Repository 어노테이션을 써주고,
각 생성자에는 @Autowired 어노테이션을 써서 의존성을 주입시켜야 한다.
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository; // 의존성 주입
}
...
}
@Repository
public class MemoryMemberRepository implements MemberRepository{
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L;
...
}
각 @Service, @Repository 어노테이션은 @Component 어노테이션의 특수한 경우로 이렇게 컴포넌트 스캔으로 자동의존관계를 설정하면 스프링빈에 등록된다.
스프링빈에 등록하는 다른 방법으로는 @Service/@Repository 어노테이션을 삭제하고 @Configuration 어노테이션이 있는 자바코드를 새로 작성하는 것이다.
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
컴포넌트 스캔방식은 쉽다는 장점이 있지만, 나중에 MemoryMemberRepository를 DbMemberRepository로 교체하기가 까다롭다. 반면 Bean 등록 방식은 return 부분에 바꿔주기만 하면 된다.