인프런에서 백기선님의 스프링 프레임워크 핵심 기술 을 공부하며 개인적으로 정리한 글입니다.
MessageSource
MessageSource
객체는 다국어에 관련된 메시지 포매팅을 해주는 역할을 담당한다.
다음 예를 살펴보면 쉽게 이해가 간다.
먼저 다음과 같은 프로퍼티 파일들을 정의하자.
# messages.properties
greeting = Hello, {0}
# messages_ko_KR.properties
greeting = 안녕, {0}
이후 다음과 같은 Runner
를 만들자.
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
MessageSource messageSource;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(
messageSource.getMessage("greeting", new String[]{"heumsi"}, Locale.KOREA))
);
System.out.println(
messageSource.getMessage("greeting", new String[]{"heumsi"}, Locale.getDefault())
);
}
}
실행하면 다음과 같은 결과가 뜬다.
안녕, 흠시
Hello, heumsi
messageSource.getMessage("key", String[] arguments, Locale.값)
이 들어가는 것을 알 수 있다.
Event
이벤트를 정의하고, 리스닝하고, 발생시키는 일련의 테스크를 설정할 수 있다.
1) 이벤트 정의
스프링 4.2 이전
스프링 4.2 버전 이전에는 다음과 같이 ApplicationEvent
를 상속받아야 한다.
public class MyEvent extends ApplicationEvent {
private int data; // 실어 보내고자 하는 데이터
private Object source;
public MyEvent(Object source) {
super(source);
}
public MyEvent(Object source, int data) {
super(source);
this.source = source;
this.data = data;
}
public int getSource() {
return source;
}
public int getData() {
return data;
}
}
스프링 4.2 이후
4.2 이후 버전에서는 Spring 관련 코드들이 모두 필요없다.
(프레임워크의 코드가 내 코드에 들어가지 않게 한다. 스프링이 추구하는 철학임.)
public class MyEvent {
private int data; // 실어 보내고자 하는 데이터
private Object source;
public MyEvent(Object source, int data) {
super(source);
this.source = source;
this.data = data;
}
public int getSource() {
return source;
}
public int getData() {
return data;
}
}
2) 핸들러(리스너) 정의
스프링 4.2 이전
ApplicationListener
를 구현해야 함.
@Component
public class MyEventHandler implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent myEvent) {
System.out.println("이벤트를 받았다. 데이터는 " + myEvent.getData());
}
}
스프링 4.2 이후
ApplicationListener
를 구현할 필요가 없다.
다만, @EventListener
를 추가해줘야 함.
메쏘드 이름도 마음대로 커스터마이징 가능하다.
@Component
public class MyEventHandler{
@EventListener
public void handle(MyEvent myEvent) {
System.out.println("이벤트를 받았다. 데이터는 " + myEvent.getData());
}
}
3) 이벤트 발생
@Component
public class AppRunner implements ApplicationRuuner {
@Autowired
AppilcationEventPublisher publishEvent;
@Override
public void run(ApplicationArguments args) throws Exception {
// 이벤트 발생시키기
publishEvent.publishEvent(new MyEvent(this, 100));
}
}
실행시키면 다음과 같이 출력된다.
이벤트를 받았다. 데이터는 100
4) 이벤트 핸들러가 여러개인 경우
다음과 같이 핸들러가 두 개인 경우 한 쓰레드에서 순차적으로 실행한다.
예를 들면 다음과 같이 2개의 핸들러가 있다고 하자.
@Component
public class MyEventHandler{
@EventListener
public void handle(MyEvent myEvent) {
System.out.println(Thread.currentThread().toString());
System.out.println("MyEventHandler " + myEvent.getData());
}
}
@Component
public class AnotherEventHandler{
@EventListener
public void handle(MyEvent myEvent) {
System.out.println(Thread.currentThread().toString());
System.out.println("AnotherEventHandler " + myEvent.getData());
}
}
이전과 동일한 Runner
를 실행하면, 다음과 같이 main 쓰레드에서 순차적으로 리스너가 실행되는 것을 알 수 있다.
Thread[main,5,main]
MyEventHandler 100
Thread[main,5,main]
AnotherEventHandler 100
만약 리스너의 순서를 부여하고 싶으면 @Order
를 핸들러 메쏘드 위에 붙여주면 된다.
값이 낮을수록 우선순위가 높다.
@Component
public class AnotherEventHandler {
@EventListener
@Order(Ordered.HIGHEST_PRECEDENCE + 2)
public void handle(MyEvent myEvent) {
...
}
}
@Component
public class MyEventHandler {
@EventListener
@Order(Ordered.HIGHEST_PRECEDENCE)
public void handle(MyEvent myEvent) {
...
}
}
이제 다시 실행하면 AnotherEventHandler
의 handle
이 먼저 실행되는 것을 알 수 있다.
Thread[main,5,main]
AnotherEventHandler 100
Thread[main,5,main]
MyEventHandler 100
5) 이벤트 핸들러 async
해당 내용은 pass.
ResourceLoader
ResourceLoader
는 리소스 관련 파일에 접근 및 로드하는 역할을 한다.
다음 예를 통해 쉽게 알 수 있다.
먼저 리소스 파일 하나를 생성하자.
# text.txt
hello spring
Runner
에 다음과 같이 ResourceLoader
를 사용하자.
@Component
public class AppRunner implements ApplicationRuuner {
@Autowired
ResourceLoader resourceLoader;
@Override
public void run(ApplicationArguments args) throws Exception {
// 리소스 로드하기
Resource resource = resourceLoader.getResource("classpath:text.txt");
// 리소스 정보 출력하기
System.out.println(resource.exists());
System.out.println(resource.getDescription());
System.out.println(Files.readString(Path.of(resource.getURL())));
}
}
실행하면 다음과 같이 출력된다.
true
class path resource [text.txt]
hello spring
'더 나은 엔지니어가 되기 위해 > 지금은 안쓰는 자바' 카테고리의 다른 글
[스프링 프레임워크 핵심 기술] 데이터 바인딩 추상화 (0) | 2020.02.21 |
---|---|
[스프링 프레임워크 핵심 기술] Resource / Validation 추상화 (0) | 2020.02.21 |
[스프링 프레임워크 핵심 기술] IoC 컨테이너 2 (0) | 2020.02.20 |
[스프링 프레임워크 핵심 기술] IoC 컨테이너 1 (0) | 2020.02.20 |
[스프링 부트 개념과 활용] 스프링 어드민 (0) | 2020.02.10 |