TomcatServletWebServerFactory와 DispatcherServlet을 빈으로 등록하기

인스턴스를 만드는 작업을 Factory Method에서 수행하도록 변경

@Configuration
@ComponentScan // 여러가지 정보에 컨테이너를 구성하는 데 필요한 hint들을 넣을 수 있음
public class HellobootApplication {
	@Bean
	public ServletWebServerFactory servletContainer() {
		return new TomcatServletWebServerFactory();
	}

	@Bean
	public DispatcherServlet dispatcherServlet() {
		return new DispatcherServlet();
	}

	public static void main(String[] args) {
		// 스프링 컨테이너 생성
		AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext() {
			@Override
			protected void onRefresh() {
				super.onRefresh(); // 생략 X

				ServletWebServerFactory serverFactory = this.getBean(ServletWebServerFactory.class);
				DispatcherServlet dispatcherServlet = this.getBean(DispatcherServlet.class);
				dispatcherServlet.setApplicationContext(this);

				WebServer webServer = serverFactory.getWebServer(servletContext -> {
					servletContext.addServlet("dispatcherServlet",dispatcherServlet)
							.addMapping("/*");
				}); // 웹서버 생성
				webServer.start(); // Tomcat Servelet Container 동작
			}
		};
		applicationContext.register(HellobootApplication.class);
		applicationContext.refresh(); // 컨테이너 초기화(빈 오브젝트 생성)
	}
}

DispatcherServlet은 Applicationcontext의 빈을 가져온 다음 주입을 해줬는 데 삭제를 하면 SpringContainer를 어디에서도 지정해 준 것이 없는 데 동작할까? ⭕️

image.png

Bean의 생명주기(lifecycle) 메서드

Type Hierarchy 보는 단축키 : ctrl + H

image.png

image.png

HelloController에 ApplicationContextAware 구현

@RestController
public class HelloController implements ApplicationContextAware {
    private final HelloService helloService;

    public HelloController(HelloService helloService) {
        this.helloService = helloService;
    }

    @GetMapping("/hello")
    public String hello(String name) {
        return helloService.sayHello(Objects.requireNonNull(name)) ;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println(applicationContext); // 서버를 띄우기만 해도 실행 됨 -> 스프링 컨테이너가 초기화되는 시점에 작업이 일어나기 때문
    }
}