객체를 생성하고 관리하고 책임지며 의존성을 관리해주는 스프링 프레임워크내의 컨테이너이다.
이때 스프링 컨테이너에서 생성되는 객체를Bean
이라고 한다.
인스턴스 생성부터 소멸까지의 인스턴스 생명주기 관리를 개발자가 아닌 컨테이너가 해준다.
따라서 개발자는 로직에 집중 할 수 있게 된다.
DL(Dependency Lookup)
DI(Dependency Injection)
각 클래스 간의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결
Constructor Injection (생성자 주입)
Setter Injection (수정자 주입)
Field Injection (필드 주입)
주로 DI를 사용한다. (DL을 사용하면 컨테이너 종속이 증가하기 때문)
BeanFactory
BeanFactory 계열의 인터페이스만 구현한 클래스는 단순히 컨테이너에서 객체를 생성하고 DI를 처리하는 기능만 제공
Bean을 등록, 생성, 조회, 반환 관리를 한다.
Bean을 조회할 수 있는 getBean() 메서드가 정의
보통 BeanFactory를 바로 사용하지 않고 ApplicationContext를 사용한다.
ApplicationContext
Bean을 등록, 생성, 조회, 반환하는 기능은 BeanFactory와 같다.
스프링의 각종 부가 기능을 추가로 제공한다.
빈 팩토리보다 어플리케이션 콘텍스트를 사용하는것이 더 좋음
스프링 컨테이너에 등록한 객체들을
빈
이라고 한다.
Bean Container 는 의존성 주입(DI)을 통해 Bean 객체를 사용할 수 있도록 해준다.
보통 Bean은 싱글톤 패턴으로 존재하게 된다.
@Controller
public class MemberController { // -> memberController 로 빈 이름이 등록
...
}
소문자
로 변경이 된다.@Controller
public class MemberController {
...
}
@ComponentScan이 @Component 어노테이션이나 @Service, @Controller, @Repository등 어노테이션이 부여된 클래스를 찾아 자동으로 Bean 등록
해당 어노테이션들은 모두 @Component 어노테이션을 포함하고 있다.
@ComponentScan은 해당 패키지 , 하위 패키지 들을 전부 확인하여 @Component가 설정된 클래스들을 빈으로 등록한다.
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() { ... }
}
ApplicationContext 를 통해 수동으로 스프링 빈 등록
자바 설정 클래스를 따로 만들어서 사용해야한다.
설정 클래스 위에 @Configuration 어노테이션을 추가한다.
특정 타입을 리턴하는 메서드를 만들고, @Bean 어노테이션을 붙이면 빈 객체가 생성이 된다.
빈들을 등록하고 필요한 곳에서 @Autowired 를 통해 의존성 주입을 받아 사용한다.
의존성 주입 : 필요한 객체에서 직접 생성하는 것이 아닌 외부로부터 객체를 받아서 사용
주의! : @Autowired는 IoC 컨테이너에 의해 관리되고 있는 Bean 클래스 내부에서만 적용이 가능
의존성 주입의 3가지 방법
@Controller
public class TestController {
private final TestService testService;
@Autowired
public TestController(TestService testService) {
this.testService = testService;
}
}
@Controller
public class TestController {
@Autowired
private TestService testService;
}
필드에 직접 @Autowired 어노테이션을 붙인다.
다만, 외부에서 변경하기 힘들다는 점, 프레임워크에 의존적이며 객체지향적으로 좋지 않음
@Controller
public class TestController {
private TestService testService;
@Autowired
public void setController(TestService testService) {
this.testService = testService;
}
}
Setter 메서드에 @Autowired 어노테이션을 붙임
언제 어디서든 변경이 가능하다는 점에서 좋지 않다.
생성자를 통한 주입이 권장하는 방법이다.
왜냐?
final로 선언하여 객체의 불변성을 보장하기 때문이다.
테스트에 용이하다는 점
스프링이 시작하게 되면
@ComponentScan 애노테이션을 통해 해당 패키지, 하위 패키지 내의 모든 @Component 애노테이션을 찾아 빈으로 등록
등록이 된 후, @Autowired 즉, DI(의존성 주입)이 필요한 것들에게 등록된 빈들을 주입하여 객체를 생성