📑
Bean
Spring IoC 컨테이너가 관리하는 자바 객체.
*IoC: Inversion of Control. 제어의 역전. 객체의 생성, 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 뜻.
컴포넌트 의존관계 설정, 설정 및 생명주기를 해결하기 위한 디자인 패턴.
IoC 컨테이너
스프링 프레임워크의 객체 생성 및 관리와 의존성 관리를 책임지는 컨테이너.
스프링 컨테이너라고도 함.
객체들은 독립적으로 동작하는 것보다 서로 상호작용하여 동작하는 경우가 많은데,
이렇게 상호작용하는 객체를 '객체의 의존성'이라고 표현함.
스프링 컨테이너에 객체들을 생성하면 객체끼리 의존성을 주입(DI, Dependency Injection)하는 역할을 함.
스프링 컨테이너에 등록한 객체들 = 빈.
인스턴스 생성부터 소멸까지의 인스턴스 생명주기 관리를 개발자가 아닌 컨테이너가 대신 함.
객체관리 주체가 프레임워크(Container)가 되기 때문에 개발자는 로직에 집중할 수 있는 장점이 있음.
- IoC 컨테이너는 객체의 생성을 책임지고, 의존성을 관리한다.
- POJO의 생성, 초기화, 서비스, 소멸에 대한 권한을 가진다.
- 개발자들이 직접 POJO를 생성할 수 있지만 컨테이너에게 맡긴다.
- 개발자는 비즈니스 로직에 집중할 수 있다.
- 객체 생성 코드가 없으므로 TDD가 용이하다.
*POJO(Plain Old Java Object): 주로 특정 자바 모델이나 기능, 프레임워크를 따르지 않는 Java Object를 지칭함.
Java Bean 객체가 대표적. (getter / setter도 POJO에 해당한다.)
*TDD: Test-Driven Development. 테스트 코드를 먼저 작성하는 개발 방법론. 선 테스트 후 개발.
스프링 컨테이너에 빈을 등록하는 두 가지 방법
1. 컴포넌트 스캔과 자동 의존관계 설정
클래스 선언부 위에 @Component 어노테이션을 사용한다.
@Controller, @Service, @Repository 어노테이션들은 @Component를 포함하고 있다.
따라서 해당 어노테이션으로 등록된 클래스들은 IoC컨테이너에 의해 자동으로 생성되어 스프링 빈으로 등록된다.
(컨테이너가 생성될 때 컴포넌트 스캔을 통해 자동으로 빈에 등록됨.)
*이 때, 빈으로 등록된 모든 클래스의 객체들은 싱글톤 패턴으로 생성된다.
2. 자바 코드로 직접(수동으로) 스프링 빈 등록
자바 설정 클래스를 만들고 @Configuration 어노테이션을 클래스 선언부 위에 추가한다.
클래스 내에 특정 타입을 리턴하는 메서드를 만들고 @Bean 어노테이션을 달면 자동으로 해당 타입의 Bean 객체가 생성된다.
@Configuration public class TestConfig{ @Bean public TestController testController(){ return new TestController(); } }
스프링 컨테이너(IoC컨테이너)의 종류
스프링 컨테이너가 관리하는 객체인 빈(Bean)의 이름을 딴 빈 팩토리(BeanFactory)와
빈 팩토리에 여러가지 컨테이너 기능을 추가한 어플리케이션 컨텍스트(ApplicationContext)가 있다.
BeanFactory
- BeanFactory 계열의 인터페이스만 구현한 클래스는 단순히 컨테이너에서 객체를 생성하고 DI를 처리하는 기능만 제공한다.
- Bean의 등록, 생성, 조회, 반환 관리를 수행한다.
- 팩토리 디자인 패턴을 구현한 것으로 BeanFactory는 빈을 생성하고 분배하는 책임을 지는 클래스이다.
- Bean을 조회할 수 있는 getBean() 메소드가 정의되어 있다.
- 보통은 BeanFactory를 바로 사용하지 않고, 이를 확장한 ApplicationContext를 사용한다.
ApplicationContext
- Bean을 등록, 생성, 조회, 반환 관리하는 기능은 BeanFactory와 같다.
- 스프링의 각종 부가 기능을 추가로 제공한다.
BeanFactory보다 더 추가적으로 제공하는 기능:
- 국제화가 지원되는 텍스트 메시지를 관리 해준다.
- 이미지같은 파일 자원을 로드할 수 있는 포괄적인 방법을 제공해준다.
- 리스너로 등록된 빈에게 이벤트 발생을 알려준다.
@Autowired & @Resource Annotation
- @Autowired : 타입(클래스)로 Bean을 지정한다.(생성자/필드/메서드에 모두 적용 가능)
- @Resource : Name으로 Bean을 지정한다.(필드/메서드에만 적용 가능)
예시
@Repository
public class CommonDao {
@Autowired
private SqlSessionTemplate sqlSession;
}
@Autowired를 사용한 예시 - sqlSession은 SqlSessionTemplate 클래스에 의존성을 가지게 된다.
@Repository
public class TestDao {
@Resource(name="BlueSqlSessionTemplate")
private SqlSessionTemplate sqlSession;
}
@Resource를 사용한 예시 - sqlSession은 BlueSqlSessionTemplate의 이름을 가진 Bean 객체에 의존성을 가지게 된다.
*name 속성을 생략하면, @Resource 어노테이션이 적용된 필드나 설정 메서드의 타입을 사용한다.
@Resource 어노테이션의 적용 순서
1. name 속성에 지정한 빈 객체를 찾는다.
2. name 속성이 없을 경우, 동일한 타입을 갖는 빈 객체를 찾는다.
3. name 속성이 없고 동일한 타입을 갖는 빈 객체가 두 개 이상일 경우, 같은 이름을 가진 빈 객체를 찾는다.
4. name 속성이 없고 동일한 타입을 갖는 빈 객체가 두 개 이상이고 같은 이름을 가진 빈 객체가 없는 경우 @Qualifier를 이용해서 주입할 빈 객체를 찾는다.