들어가며
스프링을 사용하면서 기존 자바보다 객체 생성, 조립, 사용을 훨씬 편하게 해준다는 것을 알았고 이에 기본적으로 Bean이라는 개념이 사용된다는 것을 알았다. 하지만 Bean이 무엇인지에 대한 의문점이 있어 정리해보았다.
스프링 빈 이란 ?
빈이란 스프링 IOC 컨테이너 가 관리하는 객체이다.
빈은 Spring IoC 컨테이너에 의해 인스턴스화, 조립 및 관리되는 객체이다.
인스턴스화 된 빈은 @Autowired를 통해 의존성 주입을 받을 수 있다.
인텔리제이에서 옆에 콩처럼 표시가 되어있다면 빈등록이 되었다는 것을 의미한다.
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
}
빈을 사용하는 이유 ?
의존성 주입에 있어서 용이하다. 싱글톤 객체를 사용함으로써 객체를 관리하기가 용이하다.
빈과 자바 객체의 차이점은 ?
Bean은 Spring IoC 컨테이너에 의해 관리되며, 자바 객체는 Ioc 컨테이너가 관리하지 않는 객체도 포함이다.
스프링 IOC 컨테이너 란 ?
IOC 라는 것은 제어의 역전 객체의 생성, 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 것. 의존관계, 생명주기 등 제어 하는 것이 역전되었다.
컨테이너는 객체의 생명주기 관리 및 생성된 인스턴스 관리하는 것을 의미한다.
이는 직접적으로 의존성을 만들지 않고, 외부에서 의존성을 가져온다고 이해할 수 있다. 제어의 역전이라는 말은 객체를 생성하고 관리하는 역할을 모두 스프링에게 위임하기에 표현된다. bean들의 생명주기를 관리할 수 있다.
스프링을 하나의 ioc컨테이너라고한다. 스프링 컨테이너는 DI라는 방식으로 객체를 외부에서 주입받아 생성하고 관리한다. 스프링 컨테이너를 빈을 생성하는측면에서 빈팩토리, 스프링컨테이너, ioc컨테이너 DI컨테이너 등등으로 사용한다.
왜 사용 할까?
객체간의 의존성을 낮추기 위해 사용한다.
스프링 컨테이너에서 싱글톤 컨테이너 역할을 해줌으로써 싱글톤 패턴의 단점을 없애고 객체의 단일성을 유지할 수 있다.
그렇기에 각각의 빈들은 싱글톤 패턴 적용을 위한 코드를 작성할 필요가 없다. 더하여 DIP, OCP, 테스트, private 생성자를 고민하지 않아도 된다.
어떻게 동작할까 ?
ApplicationContext는 beanFactory를 포함한 다양한 기능을 하는 인터페이스를 상속한다.
beanFactory보다는 더 많은 기능을 할 수 있는 ApplicationContext를 자주 사용한다.
둘의 차이점은 빈 생성 시기에 있다.
ApplicationContext는 애플리케이션 실행 시 빈을 로딩한다.
beanFactory는 애플리케이션 실행 중 빈을 사용 시 빈을 로딩한다.
왜 이런 차이가 있을까 ?
자주 사용되지 않는 빈을 계속 ioc컨테이너에 두고 있을 필요가 없다. 자원을 아끼기 위해 실제 빈을 사용할 경우에만 로딩하며, 자주 사용될 경우 컨테이너에 올려놓고 사용하면 좋기 때문이다.
스프링 컨테이너 빈 생명주기
- 스프링 컨테이너가 생성된다.
- 스프링 빈을 생성한다.
- 의존 관계를 주입한다.
- 초기화 콜백 메세지 호출
- 빈 사용 및 호출
- 소멸 콜백 메세지 호출
- 스프링 종료
자바 빈 등록은 어떻게 하나 ?
어노테이션 이용
@~ 와 같은 기능을 어노테이션이라고한다. 이런 어노테이션은 코드에 추가되면 메타데이터로써 특별한 기능을 수행할 수 있다.
빈 등록을 위해서는 @Component 어노테이션을 이용해 스프링이 확인하고 자체적으로 빈을 등록시킨다.
@Service, @Controller, @Repository와 같은 어노테이션도 빈 등록이 가능한데 아래와 같이 선언이 되어있기에 사용 가능하다.
Bean Configuration 이용
아래와 같이 Configuration file에 직접 Bean을 등록 할 수 있다.
@Configuration
public class Config {
@Bean
public Controller Controller() {
return new Controller;
}
}
빈이름은 메소드 이름을 사용한다. 직접 부여도 가능하다.
빈이름은 항상 다른이름을 부여해야함. 같으면 무시되거나 기존 빈을 덮어버리거나 오류발생한다.
빈 스코프란 ?
말 그대로 스프링 빈이 사용되어지는 범위이다. 스프링 빈이 애플리케이션이 작동되는 동안 어떻게 사용할 것인지에 대해 결정하는 것이다. 기본적으로 SingleTon으로 작동한다.
singleton - 앱이 구동되는 동안 하나만 사용
스프링 컨테이너 생성 시점에 초기화 메소드가 실행된다.
@Scope("singleton")
static class SingleTon{
}
@Test
void singleTon_Test(){
ApplicationContext ac = new AnnotationConfigApplicationContext(SingleTon.class);
SingleTon singleTon1 = ac.getBean(SingleTon.class);
SingleTon singleTon2 = ac.getBean(SingleTon.class);
System.out.println("singleTon1 = " + singleTon1);
System.out.println("singleTon2 = " + singleTon2);
Assertions.assertThat(singleTon1).isEqualTo(singleTon2);
}
prototype - 매번 새로운 빈을 사용
스프링 컨테이너에서 빈을 조회할 때 생성되고 초기화한다.
매번 사용할 때마다 의존관계 주입이 완료된 새로운 객체가 필요할 때 쓰면된다. 하지만 잘 안쓴다.
@Scope("prototype")
static class ProtoType{
}
@Test
void protoType_Test(){
ApplicationContext ac = new AnnotationConfigApplicationContext(ProtoType.class);
ProtoType protoType1 = ac.getBean(ProtoType.class);
ProtoType protoType2 = ac.getBean(ProtoType.class);
System.out.println("protoType1 = " + protoType1);
System.out.println("protoType2 = " + protoType2);
Assertions.assertThat(protoType1).isNotEqualTo(protoType2);
}
reqeust - http request 라이프사이클 마다 사용
동시에 여러 http요청이 오면 어떤 요청인지 구별하기 힘든데 이 때 구별하기에 좋다.
http 요청 당 하나씩 생성되고 요청이 끝나는 시점에 소멸된다.
@Component
@Scope(value = "request")
public class request {
}
session - http session 라이프사이클 마다 사용
application - ServletContext라이프 사이클 마다 사용
websocket - Websocket 라이프 사이클 마다 사용
singleTon 빈 안에서 prototype 빈을 사용해도 된다.
'코코코딩공부 > Spring' 카테고리의 다른 글
[Spring] Dispatcher Servlet이란 ? & 미션 에서 찾아보기 (0) | 2023.04.30 |
---|---|
[Spring] Servlet 이란 ? (0) | 2023.04.30 |
[Spring] 어떤 객체를 빈으로 등록해야 할까 ? (1) | 2023.04.23 |
[Spring] 테스트 DB Failed to load ApplicationContext 에러 (0) | 2023.04.18 |
[Architecture] Layered Architecture (3) | 2023.04.15 |