스프링 부트가 무엇인지 궁금하면 레퍼런스 문서를 보세요!
⇒ 스프링 부트는 stand-alone, 업무에 사용할 수 있는 수준의 스프링 기반 애플리케이션을 쉽게 만들 수 있도록 만들어주는 프레임워크라고 생각하면 된다. (스프링에서 무엇을 선택할지 고민을 줄여주는 도구)
⇒ 스프링을 사용하는 것의 Best-Practice들이 적용되어 있음.
가능하면 인텔리제이 상용버전을 사용하세요.
Java 11 사용하셨음 (Java8은 이제 구닥다리...)
서비스를 시작하자마자 무언가를 하고싶다!
초기화하는 코드를 Spring안의 Bean으로 만들고 싶다.
CommandLineRunner, ApplicationRunner 둘 다 인터페이스
인터페이스를 구현하는 빈을 실행시켜줌
@EventListener ⇒ ApplicationReadyEvent를 사용하면 된다.
오픈소스는 소스코드를 볼 수 있다는 것이 장점
@FunctionalInterface
abstract 메소드를 가지는 심플한 인터페이스 람다로 사용할 수 있음.
CommandLineRunner
run 하면 varargs로 받음. ⇒ CommandLine에서 넘어오는 파라미터만 받겠다.
특별한 경우가 아니면 ApplictaionRunner
를 사용하심.
받는 인자의 형태가 다르다. (별로 큰 차이 없이 된다)
Dave Syre ⇒ 유명하신 분
Application에 일반 class로 선언해서 만드셨음.
@Component // Streotype으로 자동으로 스캔해서 빈등록
class MyCLRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("Hello CommandLineRunner");
}
}
일반적으로 이렇게 만들지 않음.
Inline으로 바로 받는 법
@Bean
public MyCLRunner myCLRunner() { // > CommandLineRunner로 바꿔줘도 됨.
return new MyCLRunner(); // InnerClass[Anonymous Class]로 만들어줘도 됨. => 람다로 바꾼다.
}
@Configuration
, 일반 클래스
빈 선언의 동작방식이 다름
@SpringBootApplication
도 빈이다.
ApplicationRunner
가 최신의 것.
@EventListener
는 스프링 초기부터 이벤트를 제공했음(이벤트 Publish → Listen이 쉬움)
@EventListener(ApplicationReadyEvent.class)
public void init() { // 어떤 종류의 Bean에 넣어도 상관 없음.
System.out.println("Hello ApplicationReadyEvent");
}
이걸 알려면 EventListener 가 어떻게 동작하는지 알아야 함.
Application Context는 알아야함 ⇒ 모르신다면 스프링 책을 좀 보세요~
Application Context를 코드로 재구성할 수 있음(ConfigurableApplicationContext
)
2003년에 만들어짐...
일단 익명클래스를 만들고, 심플하게 만들 수 없으면 클래스로 뽑으심.
Abstractclass도 익명클래스로 만들 수 있음.
ac.addApplicationListener(new ApplicationListener<ApplicataionEvent>() {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("Hello ApplicationEvent: " + event);
}
});
ac.publishEvent(new ApplicataionEvent(ac)) {
});
Application Context는 Bean을 모두 들고있는 Container
ac.addApplicationListener(new ApplicationListener<MyEvent>() {
@Override
public void onApplicationEvent(MyEvent event) {
System.out.println("Hello ApplicationEvent: " + event);
}
});
ac.publishEvent(new MyEvent(ac, "TobySpringBoot Event"));
}
// 4.2 이상을 쓴다면
@EventListenr
public void onMyEvent(MyEvent event) {
System.out.println("Hello My Event " + event.getMessage());
}
// 4.2 이상을 쓴다면
@EventListenr(MyEvent.class)
public void onMyEvent2() {
System.out.println("Hello My Event");
}
static class MyEvent extends ApplicationEvent {
public MyEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
명시적으로 Bean을 주입 받는 방법도 있지만
결합을 끊고 싶다면 Listener를 구현해서 할 수 있음.
Event와 Listener의 관계는 기본적으로 Multicasting입니다.
EventListner
는 여러개의 이벤트를 받도록 만들 수도 있습니다.
Custom EventListener 만들기 ⇒ @EventListener
애노테이션 상속(없지만 그런의미로)은 애노테이션을 붙여주면 됨.
애노테이션 만들 때, 참고할 것
Target 어디에, 디폴트가 있지만 지정해줍시다.
Retention 언제까지, 이것도 지정해줍시다.
기능을 공부할 때, 이런 사용법이 있구나? 로 끝내기보다는 도대체 얘는 어떤 메커니즘에 의해서 동작하는거지? 어느 시점에 호출이되고? 얘랑 연관된 이벤트는 뭐지? 같은 생각을 해보자. 그런 생각이 든다면 그냥 IDE의 기능을 사용해서 볼 수 있음. 심지어 디버깅도 가능
https://www.jetbrains.com/help/idea/viewing-structure-and-hierarchy-of-the-source-code.html
상속하는 것도 단축키로 확인 가능 (^H Type Hierarchy) 이 클래스를 상속하는건 누군지
Cmd+F12는 파일 구조를 보여주는 단축키 클래스 전체 메소드, 생성자가 다나옴
call hierarchy (ctrl+opt+H) 이 메소드를 어디서 호출하는지
shift+Cmd+H 메소드를 어떤 클래스, 인터페이스에서 선언하고 오버라이드했는지
Ready와 Started의 차이가 뭘까? 라는 의문이 들어야함.
Ready 는 애플리케이션이 서비스 요청을 받을 준비가 되었다.
Started 리프레시가 되면 ApplicationRunner와 CommandLineRunner가 실행되기 전에
Started ⇒ Ready 순서임. (초기화 작업의 순서)
어떤식으로 초기화하는 방법, 순서를 알고싶다. IDE를 쓰세요!
SpringApplication.run(String... ) 이건 스프링부트의 핵심 뼈대
스프링 환경정보를 가져오는 것은 중요.
Spring Factory 매커니즘 중요함.
stopWatch 스프링 내부에 있는것 시간 체크할 때 유용함.
Q&A
application.properties 는 어디서 읽어들이나요? ⇒ 스프링 부트 소스를 받아서 찾아볼 것 같아요.(토비님이라면! 본받자!)
유쾌한 스프링... 오픈카톡방