ååãã¡ãã»ãŒãžãã¥ãŒã䜿ã£ãã¢ããªã±ãŒã·ã§ã³éã®éåæé£æºãåŠã³ãŸãããããã¯ã·ã¹ãã éã®é£æºãå¹çåããæè¡ã§ããã
ä»åã¯ãåäžã®ã¢ããªã±ãŒã·ã§ã³å ã§ãç¹ã«I/OåŠçïŒãããã¯ãŒã¯éä¿¡ãDBã¢ã¯ã»ã¹ïŒã«ãããæ§èœãéçãŸã§åŒãåºãããã®èšèšææ³ã**ãªã¢ã¯ãã£ãããã°ã©ãã³ã°ïŒReactive ProgrammingïŒ**ã®åºæ¬ãåŠã³ãŸãã
Spring Frameworkã§ã¯ããã®ãªã¢ã¯ãã£ãããã°ã©ãã³ã°ãå®çŸããããã« Spring WebFlux ã Project Reactor ãäžæ žãæ ã£ãŠããŸãã
1. ãªããªã¢ã¯ãã£ãããã°ã©ãã³ã°ãå¿ èŠãïŒ
ãããŸã§ã®Spring MVCã§æ±ã£ãŠããåŠçã¯ãã»ãšãã©ã**åæåŠçïŒããããã³ã°ïŒ**ã§ããã
- ããããã³ã°ïŒåæI/OïŒ: å€éšAPIãžã®ãªã¯ãšã¹ããDBã¢ã¯ã»ã¹ãçºçãããšããã®åŠçãå®äºããŠçµæãè¿ã£ãŠãããŸã§ã**ã¢ããªã±ãŒã·ã§ã³ã®ã¹ã¬ããã¯åŸ æ©ïŒãããã¯ïŒ**ããŸããã¹ã¬ããããããã¯ãããŠããéããã®ã¹ã¬ããã¯ä»ã®ãªã¯ãšã¹ããåŠçã§ããã倿°ã®åææ¥ç¶ã«åŒ±ããªããŸãã
**ãªã¢ã¯ãã£ãããã°ã©ãã³ã°ïŒãã³ããããã³ã°I/OïŒã¯ãã¹ã¬ãããåŸ æ©ãããŸãããI/OåŠçäžã«ã¹ã¬ããããããã¯ããã代ããã«ããã®ã¹ã¬ããã¯å¥ã®ãªã¯ãšã¹ãåŠçã«åãæ¿ãããŸããI/OåŠçãå®äºãããããããŒã¿ãå©çšå¯èœã«ãªã£ãããšããéç¥ïŒã€ãã³ãïŒ**ãå±ããåŠçãåéããŸãã
- ã¡ãªãã: ã¹ã¬ããã®å©çšå¹çãæ¥µéãŸã§é«ãŸããå°æ°ã®ã¹ã¬ããã§å€§éã®åææ¥ç¶ãåŠçã§ããããã«ãªããŸãã
2. ãªã¢ã¯ãã£ãããã°ã©ãã³ã°ã®æ žïŒProject Reactor
Spring WebFluxïŒãªã¢ã¯ãã£ããªWebãã¬ãŒã ã¯ãŒã¯ïŒã®åºç€ãšãªã£ãŠããã®ããProject Reactorãšããã©ã€ãã©ãªã§ããReactorã¯ãéåæã§çºçããããŒã¿ãæ±ãããã®2ã€ã®äž»èŠãªåãæäŸããŸãã
2-1. MonoïŒã¢ãïŒ
- æå³: 0ä»¶ãŸãã¯1ä»¶ã®ããŒã¿ããŸãã¯ãšã©ãŒãéåæçã«åŠçããã³ã³ããã
- çšé: åäžã®ãªããžã§ã¯ãããåŠçã®å®äºéç¥ïŒVoidïŒãæ±ãå Žåã«äž»ã«äœ¿çšãããŸãïŒäŸïŒåäžã®ãŠãŒã¶ãŒããŒã¿ååŸãPOSTãªã¯ãšã¹ãã®ã¬ã¹ãã³ã¹ïŒã
2-2. FluxïŒãã©ãã¯ã¹ïŒ
- æå³: 0件以äžã®è€æ°ä»¶ã®ããŒã¿ã¹ããªãŒã ããŸãã¯ãšã©ãŒãéåæçã«åŠçããã³ã³ããã
- çšé: ãªã¹ããã³ã¬ã¯ã·ã§ã³ãç¶ç¶çãªã¹ããªãŒã ããŒã¿ïŒäŸïŒè€æ°ã®ãŠãŒã¶ãŒãªã¹ããWebSocketããã®ç¶ç¶çãªããŒã¿ïŒãæ±ãå Žåã«äž»ã«äœ¿çšãããŸãã
2-3. ãªã¢ã¯ãã£ãã®åºæ¬æäœ
MonoãFluxã¯ãããŒã¿ã**ã¹ããªãŒã ïŒæµãïŒ**ãšããŠæ±ããã¡ãœãããã§ãŒã³ã§åŠçãç¹ããŠããã®ãç¹åŸŽã§ãã
Java
import reactor.core.publisher.Flux;
public void reactiveExample() {
// 1. Fluxã®çæ (ããŒã¿ã®çºè¡å
/Publisher)
Flux<String> names = Flux.just("Alice", "Bob", "Charlie")
// 2. åŠçã®å®çŸ© (ããŒã¿ãæµããŠãããå®è¡ãããæäœ)
.map(name -> name.toUpperCase()) // å
šãŠå€§æåã«å€æ
.filter(name -> name.startsWith("A")) // 'A'ã§å§ãŸããã®ã ãæ®ã
// 3. 賌èªïŒSubscription/ConsumerïŒ
// å®éã«ããŒã¿ãæµãå§ããã®ã¯ãsubscribe()ãåŒã°ããåŸ
.subscribe(
name -> System.out.println("åä¿¡ããŒã¿: " + name), // ããŒã¿åä¿¡æã®åŠç
error -> System.err.println("ãšã©ãŒãçºç: " + error), // ãšã©ãŒçºçæã®åŠç
() -> System.out.println("ã¹ããªãŒã å®äº") // å®äºæã®åŠç
);
}
3. Spring WebFluxãšã®é¢ä¿
第33åã§åŠãã WebClient ã®æ»ãå€ã Mono ã Flux ã§ãã£ãã®ã¯ãWebClientããã®ãªã¢ã¯ãã£ããªä»çµã¿ïŒProject ReactorïŒã®äžã«æ§ç¯ãããŠããããã§ãã
Spring WebFluxç°å¢ã§ã¯ãControllerã®æ»ãå€ãMonoãFluxã«ãªããŸãã
Java
// Spring WebFluxç°å¢ã®Controller
@RestController
public class ItemController {
// Mono<Item>ãè¿ããã¯ã©ã€ã¢ã³ããžã®ã¬ã¹ãã³ã¹ã¯ãããŒã¿ãå°ç次第éä¿¡ãããïŒãã³ããããã³ã°ïŒ
public Mono<Item> getItemDetail(Long id) {
// ... (Repositoryãããã³ããããã³ã°ã§ããŒã¿ãååŸããåŠç)
}
}
Spring WebFluxã¯ãåŸæ¥ã®ãµãŒãã¬ããã³ã³ããïŒTomcatãªã©ïŒã§ã¯ãªããNettyãªã©ã®ãã³ããããã³ã°I/Oã«ç¹åãããµãŒããŒãããã©ã«ãã§äœ¿çšããŸãã
4. ããã¯ãã¬ãã·ã£ãŒïŒBackpressureïŒ
ãªã¢ã¯ãã£ãããã°ã©ãã³ã°ã®éèŠãªæŠå¿µã«ããã¯ãã¬ãã·ã£ãŒããããŸãã
- åé¡ç¹: ããŒã¿ã®çºè¡å ïŒãããã¥ãŒãµãŒïŒããããŒã¿ã®åŠçé床ã远ãã€ããªãã»ã©å€§éã®ããŒã¿ãéãã€ããå ŽåãåŠçåŽïŒã³ã³ã·ã¥ãŒããŒïŒããã³ã¯ããŠããŸãå¯èœæ§ããããŸãã
- ããã¯ãã¬ãã·ã£ãŒ: ã³ã³ã·ã¥ãŒããŒããããã¥ãŒãµãŒã«å¯ŸããŠããã以äžéããªãã§ãããšNåã ããªãåŠçã§ãããããšä¿¡å·ãéããããŒã¿ã®æµéã調æŽããä»çµã¿ã§ãã
ããã«ãããã·ã¹ãã ãéè² è·ã«ãã£ãŠåæ¢ããã®ãé²ããåŠçèœåãè¶ ããªãããã«å®å®ããåäœãä¿èšŒãããŸãã
â æ¬æ¥ã®ãŸãšã
- ãªã¢ã¯ãã£ãããã°ã©ãã³ã°ã¯ãI/OåŠçäžã«ã¹ã¬ãããåŸ æ©ãããªããã³ããããã³ã°I/Oãå®çŸããå°æ°ã®ã¹ã¬ããã§å€§éã®åæãªã¯ãšã¹ããåŠçããã
- Springã®ãªã¢ã¯ãã£ãåºç€ã¯ Project Reactor ã§ãããããŒã¿ãæ±ãäž»èŠãªåãšããŠMonoïŒ0ã1ä»¶ïŒãšFluxïŒ0件以äžïŒãããã
- MonoãšFluxã¯ãã¡ãœãããã§ãŒã³ã«ãã£ãŠéåæã®åŠçãããŒãå®çŸ©ãã**subscribe()**ãåŒã°ãããŸã§ããŒã¿ã¯æµãå§ããªãïŒæ æ°ãªå®è¡ïŒã
- ããã¯ãã¬ãã·ã£ãŒã¯ãããŒã¿ã®æµãã®é床ãã³ã³ã·ã¥ãŒããŒåŽãå¶åŸ¡ããä»çµã¿ã§ãããã·ã¹ãã ã®å®å®æ§ãä¿ã€ã
ð æ¬¡åäºå
ããã§ãJavaã®ãªã¢ã¯ãã£ãããã°ã©ãã³ã°ã®æ žå¿ã«è§Šããããšãã§ããŸããã
次åã¯ãå š50åè¬åº§ã®ç·ä»äžããšããŠããããŸã§åŠãã ç¥èãçµ±åããSpring Bootã¢ããªã±ãŒã·ã§ã³ã®æçµçãªæ§èœãã¥ãŒãã³ã°ãšæ¹åã«é¢ããç·ãŸãšããè¡ããŸãã
次åïŒã第49åãç·ä»äžãïŒãSpring Bootã®æçµæ§èœãã¥ãŒãã³ã°ãšæ¹åãã€ã³ãã ã«ãæåŸ ãã ããïŒ


ã³ã¡ã³ã