- ๋ชฉ์ฐจ
- ๋ค์ด๊ฐ๋ฉฐ
- ๊ฐ์
- ์ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํ๋๊ฐ?
- ์ด๋ฒคํธ๋ฅผ ํ์ฉํ ๊ตฌํ
- ๋ง์น๋ฉฐ
- ์ฐธ๊ณ
์ผ์ ๊ท๋ชจ์ด์์ ํ๋ก์ ํธ๋ฅผ๋ณด๋ฉด ๋๋ถ๋ถ ์ด๋ฒคํธ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋ค.
์ด๋ฒคํธ ๊ธฐ๋ฐ์ด๋ผํ๋ฉด ๋ณดํต์ ์ด๋ฒคํธ ์์ฑ๊ณผ CQRS์ ๋ํด์ ๋ง์ด ์๊ธฐํ๋ค.
์ด๋ฒ ๊ธ์ ๊ตฌ์ฒด์ ์ผ๋ก ์ด๋ฒคํธ ์์ฑ๊ณผ CQRS์ ๋ํด์ ๋ค๋ฃจ๊ธฐ ์ ์, ์คํ๋ง์ ์ฌ์ฉํด์ ์ด๋ฒคํธ๋ฅผ ๋ค๋ฃจ๋ Hello World ์์ค์ ๊ธ์ ์์ฑํด๋ณด๊ณ ์ํ๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ๋จํ ์์๋ฅผ ํตํด ์ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํ๋์ง์ ๋ํด์๋ ๋ค๋ฃฌ๋ค.
๋ณธ ๊ธ์ ์๋ ํ๊ฒฝ์ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ๋์์ต๋๋ค.
- Spring Boot 2.6.4
- Lombok 1.18.22
์ ์ฒด ์์ค ์ฝ๋๋ Github์ ์ฐธ๊ณ ํ๋ฉด ๋๋ค.
์คํ๋ง์ ์ฃผ๋ก ์ฌ์ฉํ๋ ๊ฐ๋ฐ์๋ผ๋ฉด ๋ชจ๋ฅผ ์ ์๋ ๊ฐ์ฒด๊ฐ ํ๋ ์๋ค.
๋ฐ๋ก ApplicationContext์ด๋ค! ๊ทธ๋ฆฌ๊ณ ์ด ApplicationContext ์ธํฐํ์ด์ค๋ ApplicationEventPublisher๋ฅผ ์์ํ๋ค. ์ด ๋ง์ ApplicationContext์ ๊ตฌํ์ฒด๋ ๋ชจ๋ ์ด๋ฒคํธ ๋ฐํ (Event Publishing)์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค๋ ๊ฒ์ด๋ค.
์คํ๋ง์์ ์ด๋ฒคํธ๋ฅผ ๋ค๋ฃฌ๋ค๋ฉด ์๋ ์ธ ๊ฐ์ง ๊ฐ์ด๋๋ผ์ธ์ ๋ฐ๋ฅด๋ฉด ๋๋ค.
- Event (์ด๋ฒคํธ)
- ์คํ๋ง ํ๋ ์์ํฌ
4.2์ด์ ๋ฒ์ ์ ์ฌ์ฉํ๋ค๋ฉดApplicationEvent๋ฅผ ์์ํ์ฌ ์ฌ์ฉํ๋ค. 4.2๋ฒ์ ์ดํ๋ผ๋ฉด POJO ๊ฐ์ฒด๋ฅผ ๊ทธ๋๋ก ์ด๋ฒคํธ ๊ฐ์ฒด๋ก์จ ์ฌ์ฉํ ์ ์๋ค.
- ์คํ๋ง ํ๋ ์์ํฌ
- EventPublisher
ApplicationEventPublisher๋ฅผ ์ฃผ์ ๋ฐ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
- EventListener
- ์คํ๋ง ํ๋ ์์ํฌ
4.2์ด์ ๋ฒ์ ์ ์ฌ์ฉํ๋ค๋ฉดApplicationListener๋ฅผ ์์ ๋ฐ ๊ตฌํํด์ผํ๋ค. 4.2๋ฒ์ ์ดํ๋ก๋@EventListener์ ๋ ธํ ์ด์ ๋ง ๋ถ์ฌ๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
- ์คํ๋ง ํ๋ ์์ํฌ
์ด๋ฒ ๊ธ์ ๊ฐ๋ฅํ ์ฝ๊ฒ ์ค๋ช ํ๊ธฐ ์ํด ์ ๋ ธํ ์ด์ ๊ธฐ๋ฐ์ ์ฝ๋๋ง์ ๊ตฌํํ์๋ค.
์ด ๊ธ์ ์ฒ์ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํด๋ณด๋ ๊ฐ๋ฐ์๋ฅผ ๋์์ผ๋ก ํ๊ธฐ์, ์ด๋ฒคํธ ์์ฑ, CQRS๋ฑ์ ๋ด์ฉ์ ์ ํ ์ธ๊ธํ์ง ์๊ณ ์ต๋ํ ๊ฐ๋จํ ์ค๋ช ํ์์ต๋๋ค.
์คํ๋ง์ด ์ด๋ฒคํธ๋ฅผ ๋ฐํํ๊ณ ์ฒ๋ฆฌํ๋๋ฑ์ ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ค๋ ๊ฒ์ ์์๋ค.
๊ทธ๋ ๋ค๋ฉด ์ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํ ๊น??
๊ฐ๋จํ ์๊ตฌ์ฌํญ์ ๊ตฌํํ๋ฉด์ ์ ์ฌ์ฉํ๋์ง ์์๋ณธ๋ค.
์๊ตฌ์ฌํญ์ ๊ฐ๋จํ๋ค. SNS ์๋น์ค๋ฅผ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํ๊ณ , ์ฌ์ฉ์๊ฐ ํ์๊ฐ์ ํ๋ฉด ์ด๋ฉ์ผ๊ณผ SMS๋ก ๊ฐ์ ์ถํ ์๋ด๋ฅผ ํ๋ค.
์ด๋ ์ด๋ฉ์ผ๋ก๋ ๊ฐ์ ์ถํ ์ฟ ํฐ์ ๋ณด๋ด์ค๋ค.
RegisterUserService.java
@Service
public class RegisterUserService {
// private final EmailSender emailSender;
// private final SMSSender smsSender;
public void register(RegisterUserCommand registerUserCommand) {
// ํ์ ๊ฐ์
System.out.println(registerUserCommand.getName() + "๋ ํ์ ๊ฐ์
์๋ฃ - DB์ ์์ํ");
// ๊ฐ์
์ถํ ์ด๋ฉ์ผ ์ ์ก (์ฟ ํฐ ํฌํจ)
System.out.println(registerUserCommand.getName() + "๋ ๊ฐ์
์ถํํฉ๋๋ค. ์ฟ ํฐ ๋ฒํธ: xxxxx");
// ๊ฐ์
์ถํ SMS ์ ์ก
System.out.println(registerUserCommand.getName() + "๋ ๊ฐ์
์ถํํฉ๋๋ค. ๋ฌธ์");
}
}์ฐ์ ์ ๋น ๋ฅธ ๊ตฌํ์ ์ํด System.out์ผ๋ก ๋์ฒดํ์ง๋ง, ์ค์ ๋ก EmailSender, SMSSender๋ฑ์ ์์กด์ฑ์ ๋ฃ์ด์ ์ฒ๋ฆฌํด์ค๋ค.
์ค์ํ ๊ฒ์ ์์กด์ฑ์ด ๋ฐ์ํ๋ค๋ ๊ฒ!
RegisterUserController.java
@AllArgsConstructor
@RestController
public class RegisterUserController {
private final RegisterUserService registerUserService;
@GetMapping("/register/{name}")
public ResponseEntity<String> register(@PathVariable String name) {
registerUserService.register(new RegisterUserCommand(name));
String successMessage = "๊ฐ์
์์ฒญ 200";
System.out.println(successMessage);
return ResponseEntity.ok(successMessage);
}
}register/binghe๋ก ๊ฐ์
์์ฒญ์ ๋ ๋ฆฌ๋ฉด ์๋์ ๊ฐ์ด ์ถ๋ ฅ๋๋ค.
๐ค ์ ์ฝ๋์ ๋ฌธ์ ์ ์ ๋ฌด์์ผ๊น?
1๏ธโฃ ์์กด์ฑ
- ๋ฌธ์
- ํ์ฌ ํ์๊ฐ์ ์๋น์ค๋ 3๊ฐ์ง์ ๋ก์ง์ด ์๋ก ๊ฐํ๊ฒ ์์กด์ ์ด๋ค. (ํ์๊ฐ์ , ์ด๋ฉ์ผ, SMS)
- ์ฆ, ๊ฐํ ๊ฒฐํฉ์ด ๋ฐ์ํ๋ฉฐ, ์ด๋ฉ์ผ๊ณผ SMS์ ์ฝ๋ ์์ ๋ง์ผ๋ก๋ ํ์ ๊ฐ์ ๋ก์ง์ ์ํฅ์ ์ค ์ ์๋ค.
- ํด๊ฒฐ๋ฒ
- ํ์๊ฐ์ , ์ด๋ฉ์ผ, SMS ๊ธฐ๋ฅ์ ์๋ก ๋ถ๋ฆฌ์ํค๋ฉด ๋๋ค.
2๏ธโฃ ์ฑ๋ฅ
- ํ์๊ฐ์
ํ๋๋ฐ 0.1์ด๋ฉด ๋์ง๋ง, ์ด๋ฉ์ผ ๋ณด๋ด๋๋ฐ 5๋ถ, SMS ๋ณด๋ด๋๋ฐ 5๋ถ์ด ๊ฑธ๋ฆฐ๋ค๊ณ ๊ฐ์ ํ๋ฉด, ํ์๊ฐ์
์ด๋ผ๋ ์ ์ฒด ๋ก์ง์ 10๋ถ๋๊ฒ ๊ฑธ๋ฆฐ๋ค.
- ํ์๊ฐ์ ์ด๋ผ๋ ํต์ฌ ๋ก์ง์ ์ ์ธํ ์ด๋ฉ์ผ๊ณผ SMS ๋ณด๋ด๋ ๋ก์ง์ผ๋ก์ธํด ํ์๊ฐ์ ์ ๋ํ ์์ฒญ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ๊ฒ์ด๋ค.
- ํด๊ฒฐ๋ฒ
- ํ์ฌ
ํ์๊ฐ์ ์์ฒญ-> ์ด๋ฉ์ผ ์ ์ก -> SMS ์ ์ก -> ํ์๊ฐ์ ์ฑ๊ณต์ ํ๋ก์ฐ๋ฅผํ์๊ฐ์ ์์ฒญ -> ํ์๊ฐ์ ์ฑ๊ณต+๋น๋๊ธฐ ์ด๋ฉ์ผ ์ ์ก + ๋น๋๊ธฐ SMS ์ ์ก๋ก ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค.
- ํ์ฌ
3๏ธโฃ ํธ๋์ญ์
- ๋ฌธ์ ์
- ํ์๊ฐ์ , ์ด๋ฉ์ผ, SMS์ ๋ก์ง์ด ์๋ก ํ๋๋ก ๋ฌถ์ฌ์๊ธฐ์ ํ์๊ฐ์ ๋์ค์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋คํด๋ ์ด๋ฉ์ผ๊ณผ SMS์ด ๋ฐ์ก๋๊ฒ๋๋ค.
- ๋๋, ๋ฐ๋๋ก ์ด๋ฉ์ผ๊ณผ SMS์ ์์ธ๋ก ํ์๊ฐ์ ์ ๋ํ ์ฒ๋ฆฌ๊ฐ ์๋ ์๋ ์๋ค.
- ์ฆ, ํ๋๋ผ๋ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๋ค๋ฅธ ๊ธฐ๋ฅ์ ์ํฅ์ ์ฃผ๊ฑฐ๋ ํฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์๋ ์๋ค.
- ํด๊ฒฐ๋ฒ
- ๋ก์ง ์์ฒด๋ฅผ ํธ๋์ญ์ ๊ธฐ๋ฐ์ผ๋ก ๋ฌถ์ด์ฃผ๋ฉด ๋๋ค.
์ด์ ์ด๋ฒคํธ ๊ธฐ๋ฐ์ ๋ฆฌํฉํ ๋ง์ ํตํด ์ ๋ฌธ์ 3๊ฐ์ง๋ฅผ ํด๊ฒฐํด๋ณธ๋ค.
์ด๋ฒคํธ์ ์คํ ๋จ๊ณ๋ ํฌ๊ฒ 3๊ฐ์ง๋ก ๋๋๋ค.
- ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๋ ๋๋ฉ์ธ๊ฐ์ ์์์ ํธ๋์ญ์ ์ฒ๋ฆฌ ์ญํ ์ ํ๋ ์๋น์ค ๋ ์ด์ด์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ฌ ์ด๋ฒคํธ ๋์คํจ์ฒ์๊ฒ ์ ๋ฌํ๋ค.
- ์ด๋ฒคํธ ๋์คํจ์ฒ๋ ์ด๋ฒคํธ์ ๋ง๋ ํธ๋ค๋ฌ๋ฅผ ์ฐ๊ฒฐํด์ค๋ค.
- ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ์ด๋ฒคํธ์ ๋ด๊ธด ๋ฐ์ดํฐ๋ฅผ ํตํด ์ฃผ์ด์ง ๊ธฐ๋ฅ์ ์คํํ๋ค.
์์กด์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ์ด๋ฒคํธ ๊ธฐ๋ฐ์ผ๋ก ๋ฆฌํฉํ ๋งํ๋ฉด ์ฝ๊ฒ ๋ถ๋ฆฌ๊ฐ๋ฅํ๋ค.
1. ์ฐ์ ์ด๋ฒคํธ๋ฅผ ๋ง๋ค์ด์ค๋ค
RegisterUserEvent.java
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class RegisteredUserEvent {
private String name;
}์ด๋ฒคํธ ํด๋์ค์๋ ์ด๋ฒคํธ ๋ฐ์ํ๊ณ ๋์ ์ฒ๋ฆฌํ ๋ ์ฌ์ฉํ ๋ฐ์ดํฐ๋ฅผ ํฌํจํด์ฃผ๋ฉด ๋๋ค.
2. ์๋น์ค ๋ ์ด์ด ๋ฆฌํฉํฐ๋ง
RegisterUserService.java
@AllArgsConstructor
@Service
public class RegisterUserService {
@Autowired
private final ApplicationEventPublisher publisher;
// ๊ธฐํ ์์กด์ฑ ์ ๊ฑฐ๋จ. (ex. EmailSender, SMSSender)
public void register(RegisterUserCommand registerUserCommand) {
// ํ์ ๊ฐ์
System.out.println(registerUserCommand.getName() + "๋ ํ์ ๊ฐ์
์๋ฃ - DB์ ์์ํ");
// ๊ฐ์
์๋ฃ ์ด๋ฒคํธ ๋ฐํ
publisher.publishEvent(new RegisteredUserEvent(registerUserCommand.getName()));
}
}๊ธฐ์กด์ Email๊ณผ SMS๋ฅผ ๋ณด๋ด๋ ๋ก์ง๊ณผ ์์กด์ฑ์ด Service์ ์กด์ฌํ๋ค๋ฉด ์ด์ ApplicationEventPublisher๋ง ์กด์ฌํ๊ฒ ๋์๋ค.
์ด๋ฅผ ํตํด ๊ฐํ ์์กด์ฑ์ ํด๊ฒฐํ ์ ์๋ค.
3. ์ด๋ฒคํธ ์ฒ๋ฆฌ
EventHandler.java
@Component
public class EventHandler {
@EventListener
public void sendEmail(RegisteredUserEvent event) {
System.out.println(event.getName() + "๋ ๊ฐ์
์ถํํฉ๋๋ค. ์ฟ ํฐ ๋ฒํธ: xxxxx");
}
@EventListener
public void sendSMS(RegisteredUserEvent event) {
System.out.println(event.getName() + "๋ ๊ฐ์
์ถํํฉ๋๋ค. ๋ฌธ์");
}
}๋ง์ง๋ง์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํด์ฃผ๋ฉด ๋๋ค.
์ด์ ์คํํ์ฌ ๋์ผํ๊ฒ ์์ฒญ(GET http://localhost:8080/register/binghe)์ ๋ณด๋ด๋ฉด ์๋์ ๊ฐ์ด ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ฒ๋๋ค.
์ด๋ฒคํธ๋ฅผ ์ ์ฉ์ํด์ผ๋ก์จ ์์กด์ฑ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์์ง๋ง, ์ฌ์ ํ ๋จ์์๋ ๋ฌธ์ ๋ ์ฑ๋ฅ์ด๋ค.
ํ์ฌ ๋ฐ๋ก ์ค์ ์ ํด์ฃผ์ง ์์์ ์๋์ ๊ฐ์ด ์ด๋ฉ์ผ๊ณผ SMS ๋ณด๋ด๋ ๋ก์ง์ด ๊ฐ๊ฐ 3๋ถ์ฉ ๊ฑธ๋ฆฐ๋ค๋ฉด, ํ์๊ฐ์ ์ ์์ฒญํ ํด๋ผ์ด์ธํธ๋ ์ ์ด๋ 6๋ถ์ด์ ์๋ต์ ๊ธฐ๋ค๋ ค์ผํ๋ค.
์ฆ, ์ฌ์ฉ์ ๊ฒฝํ์ด ๊ต์ฅํ ๋จ์ด์ง๋ฉฐ, ์๋ฒ ์ ์ฅ์์๋ ์ค๋ ๋๋ฅผ ์ค๋ซ๋์ ์ก์๋๋ ๊ฒ์ด๊ธฐ์ ์ฑ๋ฅ์ ์น๋ช ์ ์ด๋ค.
์ผ๋ถ๋ฌ ๋ง๋ ์ด๋ฉ์ผ๊ณผ SMS์ ๋ณด๋ด๋ 3๋ถ์ฉ ๊ฑธ๋ฆฌ๋ ์ฝ๋.
@Component
public class EventHandler {
@EventListener
public void sendEmail(RegisteredUserEvent event) throws InterruptedException {
Thread.sleep(3_000); // 3์ด๊ฐ sleep
System.out.println(event.getName() + "๋ ๊ฐ์
์ถํํฉ๋๋ค. ์ฟ ํฐ ๋ฒํธ: xxxxx");
}
@EventListener
public void sendSMS(RegisteredUserEvent event) throws InterruptedException {
Thread.sleep(3_000); // 3์ด๊ฐ sleep
System.out.println(event.getName() + "๋ ๊ฐ์
์ถํํฉ๋๋ค. ๋ฌธ์");
}
}์ด๋ ํ์ฌ ๋๊ธฐ์ ์ผ๋ก ํ์๊ฐ์
์์ฒญ-> ์ด๋ฉ์ผ ์ ์ก -> SMS ์ ์ก -> ํ์๊ฐ์
์ฑ๊ณต๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ ๋ฌธ์ ์ด๋ค.
ํ์๊ฐ์
์์ฒญ -> ํ์๊ฐ์
์ฑ๊ณต + ๋น๋๊ธฐ ์ด๋ฉ์ผ ์ ์ก + ๋น๋๊ธฐ SMS ์ ์ก๋ก ๋ฐ๊ฟ์ฃผ๋ฉด ์ฑ๋ฅ์ ๋ํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
1. @Async ์ถ๊ฐ
EventHandler.java
@Component
public class EventHandler {
@Async // ๋น๋๊ธฐ
@EventListener
public void sendEmail(RegisteredUserEvent event) throws InterruptedException {
Thread.sleep(3_000);
System.out.println(event.getName() + "๋ ๊ฐ์
์ถํํฉ๋๋ค. ์ฟ ํฐ ๋ฒํธ: xxxxx");
}
@Async // ๋น๋๊ธฐ
@EventListener
public void sendSMS(RegisteredUserEvent event) throws InterruptedException {
Thread.sleep(3_000);
System.out.println(event.getName() + "๋ ๊ฐ์
์ถํํฉ๋๋ค. ๋ฌธ์");
}
}๋น๋๊ธฐ๋ก ์ฒ๋ฆฌํ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฉ์๋์ @Async๋ฅผ ์ถ๊ฐํด์ค๋ค.
2. @EnableAsync ์ถ๊ฐ
SpringEventApplication.java
@EnableAsync
@SpringBootApplication
public class SpringEventApplication {
public static void main(String[] args) {
SpringApplication.run(SpringEventApplication.class, args);
}
}Configurationํ์ผ ํน์ ์คํ๋ง ์คํ Application์ @EnableAsync๋ฅผ ์ถ๊ฐํด์ค๋ค.
์ด์ ์คํํด๋ณด๋ฉด ์๋์ ๊ฐ์ด ํ์๊ฐ์ ์ฑ๊ณต์ ๋ํ ๊ฒฐ๊ณผ๊ฐ ๋จผ์ ๋์ค๊ณ ์ด๋ฉ์ผ๊ณผ SMS๋ก ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
์ด๋ฅผ ํตํด ํ์๊ฐ์ ์ ํต์ฌ ๋ก์ง์ ๋น ๋ฅด๊ฒ ์คํ๋๊ณ ํด๋ผ์ด์ธํธ์๊ฒ ๊ฒฐ๊ณผ๋ฅผ ์๋ ค์ค ์ ์๊ฒ ๋๋ค!
์ง๊ธ๊น์ง ๊ตฌํํ ์ฝ๋๋ ํ์๊ฐ์ ๋์ค์ ์์ธ๊ฐ ๋ฐ์ํด๋ ์ด๋ฉ์ผ๊ณผ SMS์ด ๋ฐ์ก๋๊ฒ๋๋ค.
์ด๋ ํ์๊ฐ์ ์ฑ๊ณต๋์ง๋ ์์๋๋ฐ, ํ์๊ฐ์ ์ถํ ์์์ ํด๋ผ์ด์ธํธ์๊ฒ ์๋ฆฌ๋ ๊ฒ์ด๋ฏ๋ก ํฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
์ผ๋ถ๋ฌ ์์ธ๊ฐ ๋ฐ์ํ๋๋ก ๋ฆฌํฉํฐ๋งํ ์ฝ๋
@AllArgsConstructor
@Transactional
@Service
public class RegisterUserService {
@Autowired
private final ApplicationEventPublisher publisher;
public void register(RegisterUserCommand registerUserCommand) {
// ํ์ ๊ฐ์
System.out.println(registerUserCommand.getName() + "๋ ํ์ ๊ฐ์
์์ฒญ - DB์ ์์ํ");
// ๊ฐ์
์๋ฃ ์ด๋ฒคํธ ๋ฐํ
publisher.publishEvent(new RegisteredUserEvent(registerUserCommand.getName()));
throw new RuntimeException("์ผ๋ถ๋ฌ ์์ธ ํฐํธ๋ฆผ");
}
}์ ์ฝ๋๋ฅผ ์คํํ์ฌ ๋์ผํ ์์ฒญ์ ๋ณด๋ด๋ฉด ์๋์ ๊ฐ์ด ๋์จ๋ค.
ํ์๊ฐ์ ์ ๋ํ ์์ฒญ์ด ์คํจํ์์๋ ์ด๋ฉ์ผ๊ณผ SMS์ด ๋ฐ์ก๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
Spring๊ณผ Spring Data JPA
Spring Data JPA์์ ์ ๊ณตํ๋ @TransactionalEventListener๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์ด ๋ฌธ์ ๋ฅผ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์๋ค.
๊ฐ์๊ธฐ ์ JPA๋๊ณ ? ์ด๋ฒ ๊ธ์ ๊ฐ ๊ธฐ๋ฅ๋ณ Hello World๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํจ์ด์ง ๊ฐ ๋ถ๋ถ์ ๊น๊ฒ ๋ค๋ฃจ๋ ๊ธ์ด ์๋๊ธฐ ๋๋ฌธ์ด๋ค.
์ ์ฝ๋๋ฅผ ์ ์ฉํ๊ธฐ ์ ์ Spring Data JPA์ ๋ํ ์์กด์ฑ์ ์ถ๊ฐํด์ฃผ์.
@TransactionalEventListener๋ @EventListener๋ฅผ ์์ํ ์ ๋
ธํ
์ด์
์ด๋ฉฐ, ํธ๋์ญ์
๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
์๋ ์ค์ ์ ์ค ์ ์๋ค.
- AFTER_COMMIT (๊ธฐ๋ณธ)
- AFTER_ROLLBACK
- AFTER_COMPLETION
- BEFORE_COMMIT
@TransactionalEventListener ๋ฆฌํฉํฐ๋ง
@Component
public class EventHandler {
@Async
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void sendEmail(RegisteredUserEvent event) throws InterruptedException {
Thread.sleep(3_000);
System.out.println(event.getName() + "๋ ๊ฐ์
์ถํํฉ๋๋ค. ์ฟ ํฐ ๋ฒํธ: xxxxx");
}
@Async
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void sendSMS(RegisteredUserEvent event) throws InterruptedException {
Thread.sleep(3_000);
System.out.println(event.getName() + "๋ ๊ฐ์
์ถํํฉ๋๋ค. ๋ฌธ์");
}
}์ด์ ์คํํด๋ณด๋ฉด ์๋์ ๊ฐ์ด ํ์๊ฐ์ ๋ก์ง์์ ์์ธ๊ฐ ๋ฐ์ํ์ฌ ๋กค๋ฐฑ๋๋ฉด ์ด๋ฉ์ผ๊ณผ SMS๋ฅผ ๋ฐ์กํ์ง ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
์ด๋ค๊ฐ? ์คํ๋ง์์ ๋ค์ํ ์ ๋ ธํ ์ด์ ์ ์ ๊ณตํด์ฃผ๊ธฐ ๋๋ฌธ์ ์ฝ๊ฒ ์ด๋ฒคํธ ๊ธฐ๋ฐ์ ํ๋ก๊ทธ๋๋ฐ์ ํ ์ ์๋ค.
๋ฌผ๋ก ์กฐ๊ธ ๊น๊ฒ ๋ค์ด๊ฐ๋ฉด ์ฝ์ง ์๋ค :) ํ์ง๋ง ์ฐจ๊ทผ์ฐจ๊ทผ ์์๋ณด๋ฉด ๋ ๋ฏ ์ถ๋ค!
๋ค์ ๊ธ์ ์ด๋ฒคํธ ์์ฑ๊ณผ CQRS์ ๋ํด์ ๋ค๋ฃฐ ์์ ์ด๋ค!





