티스토리 뷰
Spring Bean Container
안녕하세요 오늘은 스프링 빈 컨테이너에 대해서 알아보겠습니다.
스프링 빈 컨테이너 역할
- 스프링 객체를 관리한다 : 컨테이너가 스스로 객체를 생성한다
1) @ComponentScan : @Component가 붙은 클래스들을 읽어서 객체로 생성한다
2) @Bean : @Bean을 이용하여 개발자가 생성하는 코드를 작성한다.
Java Configure
- 이전 버전의 스프링에서는 XML로 설정을 하였으나, 현재 스프링 버전에서는 어노테이션으로 지원한다.
그렇다면 우리가 메인 실행파일에서 보는 @SpringBootApplication이란 무엇일까?
웹 어플리케이션을 실행할 때 자주 보지만 그 의미에 대해서는 깊이 생각한 적이 없었다.
@SpringBootApplication은 3가지 성격을 가진 어노테이션으로 구성된다.
1) @Configuration : 클래스에 이 어노테이션이 붙어 있으면 스프링은 해당 클래스를 Java config로 간주한다.
2) @ComponentScan : 컴포넌트 검색기능을 가진 어노테이션이다. 스프링은 기본적으로 객체를 자동으로 생성하여 관리하기 때문에 @Component 어노테이션이 있는 클래스들을 스프링 컨테이너가 생성해준다. @ComponentScan는 특별히 basePackage를 지정하지 않아도 main class가 위치한 패키지를 Root package로 하여 그 이하의 모든 컴포넌트 클래스들을 검색하여 빈으로 등록한다.
FirstApplication.class는 메인 클래스이다. 이 클래스는 examples.boot.first 패키지에 위치하고 있고 이곳이 컴포넌트 스캔의 루트 패키지가 된다. 즉 FirstApplication이 위치하고 있는 example.boot.first 패키지가 기준이 되어 그 하위에 있는 모든 컴포넌트들을 검색한다.
3) @EnableAutoConfiguration : 어플리케이션에 추가된 설정들을 자동으로 추가해주는 어노테이션
스프링에 없어서는 안되는 @SpringBootApplication 어노테이션을 살펴보자
@SpringBootApplication
public class FirstApplication {
// 프로그램 시작점
public static void main(String[] args) {
SpringApplication.run(FirstApplication.class, args);
}
}
@SpringBootApplication을 클릭하고 들어가면
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
@SpringBootConfiguration 어노테이션을 확인할 수 있다. 이 어노테이션을 클릭하면
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
다음과 같이 @Configuration 어노테이션이 붙은 인터페이스가 나온다.
위와 같이 클래스에 @Configuration이 있으면 스프링은 Java Configure 설정 클래스로 간주하여 Bean으로 등록한다.
컴포넌트 스캔 : @Component를 검색
@ComponentScan :
- 루트 패키지 이하의 클래스 중 @Component 어노테이션이 붙은 클래스들을 검색한다.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@Configuration 어노테이션을 클릭하면
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
@Component 어노테이션을 확인할 수 있다.
즉 이 뜻은 @Configuration 클래스도 컴포넌트로서 스캔의 대상이 된다.
위와 같이 @Configuration, @ComponentScan, @Component 어노테이션에 대해 알아보았습니다. 그렇다면 누가 빈을 생성해주는 역할을 하는 것일까요?? 바로 스프링 빈 컨테이너가 해줍니다.
스프링 빈 컨테이너는 인스턴스의 생명주기를 관리합니다. 컨테이너의 종류는 ApplicationContext와 BeanFactory 2가지로 나누어지는데, 둘의 차이점은 쉽게 말하면 ApplicationContext가 BeanFactory의 향상된 버전입니다.
ApplicationContext
ApplicationContext를 구현하고 있는 클래스들이 객체 관리 및 의존성 주입 가능하게 해준다. 오브젝트 생성, 관계 설정, 만들어지는 방식, 자동 생성, 후처리 등 여러가지 일들을 한다. 그리고 BeanFactory를 상속 받고 있다.
Spring의 역할
1. 스프링은 객체를 관리한다.
- 1. 객체 생성 : @Component 어노테이션을 포함한 클래스들의 인스턴스를 자동으로 생성한다.
@Component의 종류
1. @Contoller - @RestController
2. @Service
3. @Repository
** 3가지 종류의 컴포넌트가 다른 이름을 가진 이유는 레이어를 구분하기 위함
@RestController : @RestController -> @Controller 안으로 들어가면 @Component 어노테이션이 있다. @Component 어노테이션이 붙어 있으면 스프링 Bean Container가 모두 객체를 생성한다(개발자가 직접 new()를 사용하는 것과 같은 역할을 한다.)
이 때 스프링의 객체 생성의 가장 큰 특징으로는 Singleton 패턴이라는 것입니다. 어떻게 하는 것 일까요?
@Bean을 이용하여 개발자가 생성하는 코드를 작성
public class FirstApplication {
// 프로그램 시작점
public static void main(String[] args) {
SpringApplication.run(FirstApplication.class, args);
}
run()에 넣어야 하는 것은 Java Config 클래스이다. 즉 FirstApplication.class를 넣는다. Java Config가 되려면 @Configuration이 붙어 있어야 한다.
@SpringBootApplication 내부에 @Configuration이 포함되어 있기 때문에 Java configure로 가능.
그럼 Java configure는 누가 읽는가? Application Context가 읽는다. 이것은 run() 안에 구현되어 있다.
examples.boot. first ---> 이하로 컴포넌트를 찾는다
FirstApplication이 examples.boot.first에 있기 때문.
examples.boot.first.service 라는 패키지 아래에 컴포넌트가 있어도 찾을 수 있다.
examples.boot.first.main 패키지에 FirstApplication 클래스가 있다면?
examples.boot.first.service 패키지의 클래스는 찾을 수 있을까? No!!
스프링은 기본적으로 객체를 관리할 때 Singleton으로 한다.
객체를 메모리에 1번만 올린다.
2. 스프링은 의존성을 관리
- setter 주입
- 생성자 주입
- @Autowired
웹에서의 스레드와 공유객체
웹에서 싱글톤 객체를 사용하게 되면 망가질 수 있다.
- 객체의 필드가 변할 수 있기 때문이다.
- synchronized 키워드를 붙이면 thread에서 발생하는 문제를 예방할 수 있다.
-
Spring Bean Container
FirstApplication : 설정 파일
@Bean
todayBean()
--> 첫 번째 호출할 때는 super.todayBean() 한번 호출
2번째 호출할 때는 프록시 객체를 바로 리턴한다.
동적생성할 때 사용하는 CGLIB를 사용한다.
http://localhost:8080/hello
1) 접속(ip, 포트번호)
2) 요청정보
- 요청라인 : GET /hello(path) 버전
- 헤더(이름의 값)
- Body : GET 방식으로 보낼 땐 없고 POST일 때 있다
- path = context path + path
1) context path : Tomcat started on port(s): 9090 (http) with context path ''
* 톰캣에는 여러개의 웹 어플리케이션이 있는데 그것들을 구분할 수 있는것이 context path이다.
2) path : 웹 어플리케이션 내부에서 맵핑
- DispatcherServlet : 모든 요청은 이곳에서 처리하도록 설정함
- DefaultServlet : 디스패쳐가 해결하지 못하는 것은 Default서블릿이 함.
--> 이 요청 정보들이 HttpServletRequest에 입력되는 것이다.
HttpServletResponse 객체는 응답을 위한 객체이다. 이것은 WAS가 만든다. 그래야 어디로 응답할지 알기 때문
<이번주 할일>
1. Java config 중심으로 찾기
2. DI 컨테이너
3. 의존성 주입 예제
'Back-end' 카테고리의 다른 글
[Spring Boot] 컨트롤러 핸들러 메소드 매개변수 타입 (1) | 2018.10.14 |
---|---|
[Spring Boot] HandlerMethodArgumentResolver (3) | 2018.10.14 |
[Spring Boot] 스프링부트 개발 준비 (0) | 2018.10.06 |
[Spring Boot] OOP에 대하여 (0) | 2018.10.06 |
[Spring Boot] Java, Spring 학습 로드맵 (0) | 2018.10.06 |
- Total
- Today
- Yesterday
- resize
- 관계대수
- 월급쟁이부자들
- 항해플러스후기
- pop_back
- 유즈케이스
- 인셉션
- 깃
- front
- 도커
- 부동산공부
- 개발자 회고
- 깃허브
- 2023년
- 항해플러스백엔드
- github
- Inception
- 파라메터
- 내년은 빡세게!!
- 재테크공부
- docker
- GIT
- 열반스쿨기초반
- Use case
- push_back
- 월부닷컴
- Spring boot
- 폭포수
- ```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
- 항해솔직후기
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |