스프링의 IoC(Inversion of Control) 컨테이너가 관리하는 자바 객체.
우리가 new 연산자를 통해 만드는 객체는 Bean이 아님.
ApplicationContext.getBean()으로 얻어질 수 있는 객체가 Bean. 즉, 스프링에서의 빈은 ApplicationContext가 알고 있는 객체, ApplicationContext가 만들어서 그 안에 담고 있는 객체를 의미함.
스프링 프레임워크 구조 (Bean은 컨테이너 하위에 존재)
컴포넌트 스캔
스프링이 빈으로 등록될 준비가 된 클래스들을 스캔하여 빈으로 등록
@Component을 붙여서 사용(@Component가 붙어있는 클래스들은 전부 컴포넌트 스캔의 대상이기 때문에)
@Component는 아래와 같이 “@Target(ElementType.TYPE)” 설정이 있기 때문에 Class 혹은 Interface에만 붙일 수 있다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
<aside> 💡 @Target 이란?
ElementType.TYPE : 클래스/인터페이스/열거타입(enum)에 지정 ElementType.CONSTRUCTOR : 생성자에 지정 ElementType.METHOD : 메소드에 지정 ElementType.FIELD : 필드에 지정 ElementType.ANNOTATION_TYPE : 어노테이션에 지정 ElementType.LOCAL_VARIABLE : 지역 변수에 지정 ElementType.PACKAGE : 패키지에 지정
</aside>
컴포넌트 스캔의 대상
@Controller : 스프링 MVC 컨트롤러로 인식
@Service : 특별한 처리는 없으나 개발자들이 핵심 비즈니스 계층을 인식하는데 도움을 줌
@Repository : 스프링 데이터 접근 계층으로 인식하고 해당 계층에서 발생하는 예외는 모두 DataAccessException 으로 변환
@Configuration : 스프링 설정 정보로 인식하고 스프링 빈이 싱글톤을 유지하도록 추가 처리
<aside> 💡 @Configuration이 싱글톤 빈을 보장하는 방식?
</aside>
Bean 설정 파일에 직접 등록
파일은 XML과 자바로 작성가능. 요즘에는 자바 설정파일을 더 많이 사용하는 추세.
파일에 @Configuration 을 붙여서 Bean 등록 전용 파일을 만든 후 @Bean 어노테이션을 사용해서 빈으로 등록
@Configuration
public class HelloConfiguration {
@Bean
public HelloController sampleController() {
return new SampleController;
}
}
⇒sampleController()에서 리턴되는 객체가 IoC 컨테이너 안에 빈으로 등록됨
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
⇒ 참고로 @Bean은 위와 같이 ElementType 설정이 “METHOD, ANNOTATION_TYPE” 이기 때문에 메소드나 어노테이션에만 붙일 수 있고, 클래스 등에는 붙일 수 없다.
@Component VS @Bean
생성자를 이용한 주입
생성자 호출 시 주입하며, 가장 권장하는 방법. 인자에 사용되는 빈을 먼저 찾고 빈으로 주입하려는 빈의 생성자를 호출.
/* 기본 사용법 */
@Service
public class UserService{
private final UserRepository userRepository;
//생성자 호출 시 주입
public UserService(UserRepository userRepository){
this.userRepository = userRepository;
}
}
/* lombok 라이브러리 사용 시 @RequiredArgsConstructor 사용하여 생성자 생략가능 */
@Service
@RequiredArgsConstructor
public class UserService{
private final UserRepository userRepository;
}
장점
Setter를 이용한 주입
Setter 메소드에서 전달받은 객체를 주입시키는 형식
@Service
public class UserService{
private UserRepository userRepository;
@Autowired
pubilc void setUserRepository(UserRepository userRepository){
this.userRepository = userRepository;
}
}
Field변수를 이용한 주입
@Autowired를 통해 필드에 바로 주입. 간단하지만 가장 권장하지 않는 방법.
@Service
public class UserService{
@Autowired
private UserRepository userRepository;
}
단점