๐ ๊ฐ๋ ์ ๋ฆฌ & ์ฌ์ ์ค๋น
1. ์ด๋ฒคํธ
Spring Boot์์ ์ด๋ฒคํธ๋ฅผ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ค์ด๊ฐ๊ธฐ ์ ์, ์ด๋ฒคํธ๋ฅผ ์ ์จ์ผํ๋์ง, ์ฌ์ฉํ๋ฉด ์ข์ ์ํฉ์ ๋ํด ๋จผ์ ์๊ฐํ๊ฒ ์ต๋๋ค. ํ์๊ฐ์ ์ ํ๊ณ ๋๋ฉด ๊ฐ์ ์ถํ ๋ฉ์ธ์ง๋ฅผ ์ ์กํ๋ ๋์์ ์ฟ ํฐ์ ์ ์กํ๋ ์๋น์ค๊ฐ ์๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
@Service
public class RegisterService {
@Autowired
ApplicationEventPublisher publisher;
public void register(String name) {
// ํ์๊ฐ์
์ฒ๋ฆฌ ๋ก์ง
System.out.println("ํ์ ์ถ๊ฐ ์๋ฃ");
// ๊ฐ์
์ถํ ๋ฉ์ธ์ง ์ ์ก
System.out.println(name + "๋์๊ฒ ๊ฐ์
์ถํ ๋ฉ์ธ์ง๋ฅผ ์ ์กํ์ต๋๋ค.");
// ๊ฐ์
์ถํ ์ฟ ํฐ ๋ฐ๊ธ
System.out.println(name + "๋์๊ฒ ์ฟ ํฐ์ ์ ์กํ์ต๋๋ค.");
}
}
์์ ๊ฐ์ด ํ์ ๊ฐ์ - ๋ฉ์ธ์ง ์ ์ก - ์ฟ ํฐ ๋ฐ๊ธ์ ๋ก์ง์ ํ๊ฒ ๋ฉ๋๋ค. ํ์ง๋ง ์ ์ฝ๋์๋ ๋ฌธ์ ์ ์ด ๋ช๊ฐ์ง ์กด์ฌํฉ๋๋ค.
1) ๊ฐํ ๊ฒฐํฉ
ํ์ฌ ํ์๊ฐ์ ์๋น์ค์ ํ์ ๊ฐ์ ๋ก์ง๋ฟ๋ง ์๋๋ผ ๊ฐ์ ์ถํ ๋ฉ์ธ์ง๋ฅผ ์ ์กํ๋ ๋ก์ง, ๊ฐ์ ์ถํ ์ฟ ํฐ์ ๋ฐ๊ธํ๋ ๋ก์ง์ด ๋ชจ๋ ์์ฌ์์ต๋๋ค. ์ด๋ ๊ฒ ์๋ก ๊ฐํ ๊ฒฐํฉ์ผ๋ก ๋ฌถ์ฌ์์ผ๋ฉด ํ์ ์ ์ง๋ณด์๊ฐ ์ด๋ ค์ธ๋ฟ๋ง ์๋๋ผ ์ฝ๋์ ๊ตฌ์กฐ๊ฐ ๋ณต์กํด์ง๊ฒ ๋ฉ๋๋ค.
2) ํธ๋์ญ์
๋ง์ฝ ๊ฐ์ ์ถํ ๋ฉ์ธ์ง๋ฅผ ์ ์กํ๋ค๊ฐ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ํ์๊ฐ์ ์ ํ ์ด๋ ฅ๊น์ง ๋ชจ๋ ๋กค๋ฐฑ์ ํ๋ ๊ฒ์ ์ ๋ ์ข์ ๋ฐฉ๋ฒ์ด ์๋๋๋ค. ์ฐจ๋ผ๋ฆฌ ํ์ ๊ฐ์ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๊ณ , ์ถํ ๋ฉ์ธ์ง์ ์ฟ ํฐ ๋ฐ๊ธ์ ๋ฐ๋ก ๊ด๋ฆฌํ๋๊ฒ ์ณ์ ๋ฐฉ๋ฒ์ ๋๋ค.
3) ์ฑ๋ฅ
๊ฐ์ ์ถํ ๋ฉ์ธ์ง๋ฅผ ์ ์กํ๋๋ฐ 3๋ถ, ์ฟ ํฐ์ ๋ฐ๊ธํ๋๋ฐ 3๋ถ์ด ๊ฑธ๋ฆฐ๋ค๊ณ ํ๋ฉด ์ด ํ์๊ฐ์ ์ 6๋ถ์ด ๊ฑธ๋ฆฌ๊ฒ ๋ฉ๋๋ค. ๋ฉ์ธ ์ด๋ฒคํธ์ธ ํ์๊ฐ์ ์ฒ๋ฆฌ ๋ก์ง์ ๋๋ด๋ฉด ์๋ธ ์ด๋ฒคํธ์ธ ๊ฐ์ ์ถํ ๋ฉ์ธ์ง ์ ์ก์ด๋ ๊ฐ์ ์ถํ ์ฟ ํฐ์ ์ ์ก์๋ฃ๊น์ง ๊ธฐ๋ค๋ฆด ํ์๊ฐ ์์ต๋๋ค.
์ฆ, ํ์๊ฐ์ ์ฒ๋ฆฌ → ๊ฐ์ ์ถํ ๋ฉ์ธ์ง ์ ์ก → ์ฟ ํฐ ๋ฐ๊ธ → ํ์๊ฐ์ ์ฒ๋ฆฌ ์๋ฃ๊ฐ ์๋, ํ์๊ฐ์ ์ฒ๋ฆฌ → ํ์๊ฐ์ ์ฒ๋ฆฌ ์๋ฃ (๊ฐ์ ์ถํ ๋ฉ์ธ์ง, ์ฟ ํฐ ๋ฐ๊ธ์ ๊ฐ์ ์ฒ๋ฆฌ ๋๋ฉด ๋ฐ๋ก ์คํ ์์)์ ์์๋ก ์คํ์ ํ๋ฉด ๋ฉ๋๋ค. ๋ฐ๋ก ์์ ๊ฐ์ ์ํฉ์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ ์ค์ ์ด๋ฒคํธ๋ฅผ ์ ์ฉํด์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ด๋ฒคํธ๋ ์์ฑ ์ฃผ์ฒด์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ด๋ฒคํธ๋ฅผ ๋ฐ์์์ผ ์ํ๋ ๊ธฐ๋ฅ์ ์คํํด์ ํ์ฒ๋ฆฌ๋ฅผ ๋์์ค๋๋ค.
2. ์ด๋ฒคํธ์ ์คํ ๋จ๊ณ
- ์์ฑ ์ฃผ์ฒด(์ฃผ๋ก ๋๋ฉ์ธ ๊ฐ์ฒด)์์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ํ๋ฉด ์ด๋ฒคํธ ๋์คํจ์ฒ์๊ฒ ์ ๋ฌํ๋ค.
- ์ด๋ฒคํธ ๋์คํจ์ฒ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ฐ๊ฒฐํด์ค๋ค.
- ์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ์ด๋ฒคํธ์ ๋ด๊ธด ๋ฐ์ดํฐ๋ฅผ ํตํด ์ํ๋ ๊ธฐ๋ฅ์ ์คํํ๋ค.
3. ์ฌ์ ์ค๋น
- ์์กด์ฑ ์ถ๊ฐ
- spring-boot-starter-web
๐ป ๊ตฌํ - ๊ฐํ๊ฒฐํฉ ํด๊ฒฐ
1. ์ด๋ฒคํธ ํด๋์ค ๋ง๋ค๊ธฐ
event/RegisteredEvent.java
public class RegisteredEvent {
private String name;
public RegisteredEvent(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
์ด๋ฒคํธ๋ ์ํ๊ฐ ๋ฐ๋ ํ์ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฒคํธ ํด๋์ค์ ์ด๋ฆ์ ๊ณผ๊ฑฐ์์ ๋ก ์ง์ด์ผํฉ๋๋ค. ๋ํ, ์ด๋ฒคํธ ํด๋์ค๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ์ดํฐ๋ฅผ ํฌํจํฉ๋๋ค.
2. ์๋น์ค ๋ง๋ค๊ธฐ
service/RegisterService.java
@Service
public class RegisterService {
@Autowired
ApplicationEventPublisher publisher; // 1
public void hello(String name) {
// ํ์๊ฐ์
์ฒ๋ฆฌ ๋ก์ง
System.out.println("ํ์ ์ถ๊ฐ ์๋ฃ");
publisher.publishEvent(new RegisteredEvent(name)); // 2
}
}
(1) ์ด๋ฒคํธ๋ฅผ ๋ณด๋ด๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ํด ApplicationEventPublisher๋ฅผ ์ฃผ์ ํด์ค๋๋ค.
(2) ํ์๊ฐ์ ์ฒ๋ฆฌ๋ฅผ ์๋ฃํ๊ณ ๋๋ฉด, publishEvent()๋ฅผ ์ฌ์ฉํด ์ด๋ฒคํธ๋ฅผ ์ ๋ฌํด์ค๋๋ค.
์ด์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ํธ๋ค๋ง์ ํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
3. ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ง๋ค๊ธฐ
event/handler/SmsEventHandler.java
@Component
public class SmsEventHandler {
@EventListener // 1
public void sendSms(RegisteredEvent event) {
System.out.println(event.getName() + "๋์๊ฒ ๊ฐ์
์ถํ ๋ฉ์ธ์ง๋ฅผ ์ ์กํ์ต๋๋ค.");
}
@EventListener
public void makeCoupon(RegisteredEvent event) {
System.out.println(event.getName() + "๋์๊ฒ ์ฟ ํฐ์ ์ ์กํ์ต๋๋ค.");
}
}
(1) @EventListener๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ก ๋ฑ๋ก์ด ๋๊ณ , ๋งค๊ฐ๋ณ์์ ์ด๋ฒคํธ ํด๋์ค๋ฅผ ์ ์ํ๋ฉด ํด๋น ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ์์ ํด์ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์์ต๋๋ค.
4. ์ปจํธ๋กค๋ฌ ๋ง๋ค๊ธฐ
controller/TestController.java
@RestController
public class TestController {
@Autowired
RegisterService service;
@GetMapping("/register/{name}")
public void register(@PathVariable String name) {
service.hello(name);
System.out.println("ํ์๊ฐ์
์ ์๋ฃํ์ด์");
}
}
ํ ์คํธ์ฉ ์ปจํธ๋กค๋ฌ๋ฅผ ๋ง๋ค์ด์ค๋๋ค. ์ด๋ฆ์ ๊ฐ์ ธ์์ ์๋น์ค๋ฅผ ํธ์ถํ๋ ๊ฐ๋จํ ์ฝ๋์ด๊ธฐ ๋๋ฌธ์ ๋ถ์ฐ ์ค๋ช ์ ์ถ๊ฐํ์ง ์๊ฒ ์ต๋๋ค.
5. ํ ์คํธ
์ด์ ๊ตฌํ์ด ๋๋ฌ์ผ๋ ํ ์คํธ๋ฅผ ํด๋ณด๊ฒ ์ต๋๋ค.
http://localhost:8080/register/์นฉ์ค๋ฐ์ผ๋ก ์ ์ํ ํ์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด๋ฉด
์ ๋๋ก ๋์ค๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค! ์๋น์ค ์ฝ๋๋ ๋ก์ง์ด ์์ด์ง ์๊ณ ๊ฒฐํฉ๋๋ ์ฝํด์ง ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.ํ์ง๋ง ๋ง์ฝ ์ถํ ๋ฉ์ธ์ง์ ์ฟ ํฐ์ ์ ์กํ๋ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฐ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ์๋น์ค ์ฝ๋๋ฅผ ์๋์ ๊ฐ์ด ์์ ํด๋ณด๊ฒ ์ต๋๋ค.
event/handler/SmsEventHandler.java
@Component
public class SmsEventHandler {
@EventListener
public void sendSms(RegisteredEvent event) throws InterruptedException {
Thread.sleep(2000); // 2์ด
System.out.println(event.getName() + "๋์๊ฒ ๊ฐ์
์ถํ ๋ฉ์ธ์ง๋ฅผ ์ ์กํ์ต๋๋ค.");
}
@EventListener
public void makeCoupon(RegisteredEvent event) throws InterruptedException {
Thread.sleep(1000); // 1์ด
System.out.println(event.getName() + "๋์๊ฒ ์ฟ ํฐ์ ์ ์กํ์ต๋๋ค.");
}
}
์๊น์ ๊ฐ์ด ์์๋๋ก ์ด๋ฒคํธ๊ฐ ์์ฑ๋๊ธด ํ์ง๋ง, ํ์ ์ถ๊ฐ ์๋ฃ —2์ด ํ→ ๊ฐ์ ์ถํ ๋ฉ์ธ์ง ์ ์ก —1์ด ํ→ ์ฟ ํฐ ์ ์ก → ํ์๊ฐ์ ์๋ฃ์ ์์๋๋ก ์์ ์ด ์งํ๋ฉ๋๋ค. ์ด ์ํฉ์ ํด๊ฒฐํ๊ธฐ ์ํด ํ์ ์ถ๊ฐ๊ฐ ์๋ฃ๋๋ฉด ์ด๋ฒคํธ๋ค์ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌํ๋ ์ถ๊ฐ ์์ ์ ์งํํ๋๋ก ํ๊ฒ ์ต๋๋ค.
๐ป ๊ตฌํ - ๋น๋๊ธฐ ์ฒ๋ฆฌ(์ฑ๋ฅ ํด๊ฒฐ)
1. @EnableAsync ์ถ๊ฐ
SpringEventApplication.java
@EnableAsync // ์ถ๊ฐ
@SpringBootApplication
public class SpringEventApplication {
public static void main(String[] args) {
SpringApplication.run(SpringEventApplication.class, args);
}
}
๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํด Application์ @EnableAsync๋ฅผ ์ถ๊ฐํด์ค๋๋ค. (Application์ด ์๋ config ํ์ผ์ ์ถ๊ฐํด๋ ๋ฌด๋ฐฉํฉ๋๋ค.)
2. @Async ์ถ๊ฐ
event/handler/SmsEventHandler.java
@Component
public class SmsEventHandler {
@Async // ์ถ๊ฐ
@EventListener
public void sendSms(RegisteredEvent event) throws InterruptedException {
Thread.sleep(2000);
System.out.println(event.getName() + "๋์๊ฒ ๊ฐ์
์ถํ ๋ฉ์ธ์ง๋ฅผ ์ ์กํ์ต๋๋ค.");
}
@Async // ์ถ๊ฐ
@EventListener
public void makeCoupon(RegisteredEvent event) throws InterruptedException {
Thread.sleep(1000);
System.out.println(event.getName() + "๋์๊ฒ ์ฟ ํฐ์ ์ ์กํ์ต๋๋ค.");
}
}
๋น๋๊ธฐ๋ก ์ฒ๋ฆฌํ ๋ฉ์๋์ @Async๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
3. ํ ์คํธ
์ด๋ฒ์๋ ํ์ ์ถ๊ฐ๊ฐ ์๋ฃ๋๋ฉด ๋ฐ๋ก ํ์๊ฐ์ ์ ์๋ฃํ๋ค๋ ๋ฉ์ธ์ง๊ฐ ๋จ๊ณ , ๊ทธ ์ดํ์ ์์ฐจ์ ์ผ๋ก ์ฟ ํฐ์ ์ ์กํ๊ณ ์ถํ ๋ฉ์ธ์ง๋ฅผ ์ ์กํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ์ด๋ฐ์์ผ๋ก ์ ๋ง ๊ฐ๋จํ๊ฒ ๋น๋๊ธฐ๋ฅผ ์ถ๊ฐํ ์ ์๊ณ , ์๊น ๋ฌธ์ ์ ์ ๋์๋ ์ฑ๋ฅ ๋ฌธ์ ์ญ์ ํด๊ฒฐํ ์ ์์ต๋๋ค!
๐ ๊ตฌํ - ํธ๋์ญ์ ํด๊ฒฐ
๊ทธ๋ ๋ค๋ฉด ์ฟ ํฐ์ ์ ์กํ๋ค ์คํจํ๋ฉด ํ์ ๋ฐ๊ธํ์ง ๋ชปํ๋ ๊ฒ์ผ๊น์? ๊ทธ๋ ์ง ์์ต๋๋ค! ์ ์์ ๋ ๊ฐ๋จํ๊ฒ @Async์ ์ถ๊ฐํ๋ ๊ฒ ์ด์ธ์ ์ฒ๋ฆฌํ์ง ์์์ง๋ง, ๋น๋๊ธฐ ์ด๋ฒคํธ ์ฒ๋ฆฌ๋ฅผ ํ๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ์ต๋๋ค.
- ๋ก์ปฌ ํธ๋ค๋ฌ๋ฅผ ๋น๋๊ธฐ๋ก ์คํํ๊ธฐ
- ๋ฉ์ธ์ง ํ๋ฅผ ์ฌ์ฉํ๊ธฐ(RabbitMQ, Kafka ...)
- ์ด๋ฒคํธ ์ ์ฅ์์ ์ด๋ฒคํธ ํฌ์๋ ์ฌ์ฉํ๊ธฐ
- ์ด๋ฒคํธ ์ ์ฅ์์ ์ด๋ฒคํธ ์ ๊ณต API ์ฌ์ฉํ๊ธฐ
์ ๋ค๊ฐ์ง ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ์ค๋ช ์ด๋ ๊ตฌํ ๋ฐฉ๋ฒ์ DDD START!๋ผ๋ ์ฑ ์ ์ค๋ช ์ด ๋์ด์์ผ๋ ๊ด์ฌ์ด ์์ผ์ ๋ถ๋ค์ ํ ๋ฒ์ฉ ์ฝ์ผ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค :)
https://shinsunyoung.tistory.com/88
Spring Boot์์ ์ด๋ฒคํธ ์ฌ์ฉํ๊ธฐ
์๋ ํ์ธ์! ์ด๋ฒ ํฌ์คํ ์์๋ Spring Boot์์ ์ด๋ฒคํธ๋ฅผ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค. ์ ์ฒด ์ฝ๋๋ Github์์ ํ์ธ์ด ๊ฐ๋ฅํฉ๋๋ค. โ๏ธ ๐ ๊ฐ๋ ์ ๋ฆฌ & ์ฌ์ ์ค๋น 1. ์ด๋ฒคํธ Spring Boot์์
shinsunyoung.tistory.com
'CS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํจ์จ์ ์ธ ์๋ฆผ๊ตฌํ๊ณผ ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ ๋ต (0) | 2024.03.28 |
---|---|
Thread ์ ํฐ์บฃ ํ๋ํ๊ธฐ (0) | 2024.03.28 |
์๋ฐ์ Record๋ก DTO๋ฅผ ๋ง๋ค์ด๋ณด์ (0) | 2024.03.13 |
Stream API์ map (0) | 2024.03.13 |
Thread, maxThread, maxConnections, accpetCount์ ์ดํด (0) | 2024.03.13 |