Context는 어떠한 상황에서 그 상황을 처리하기 위해 필요한 정보
ServletContext
는 Servlet이 Servlet Container와 통신하기 위해서 필요한 정보를 제공하는 인터페이스ApplicationContext
는 애플리케이션의 정보를 제공하는 인터페이스SecurityContext
는 애플리케이션 사용자의 인증 정보를 제공하는 인터페이스Reactor에서는 Operator 체인상의 서로 다른 Thread들이 Context의 저장된 데이터에 손쉽게 접근할 수 있다.
Mono
.deferContextual(ctx ->
Mono
.just("Hello" + " " + ctx.get("firstName"))
.doOnNext(data -> log.info("# just doOnNext : {}", data))
)
.subscribeOn(Schedulers.boundedElastic())
.publishOn(Schedulers.parallel())
.transformDeferredContextual(
(mono, ctx) -> mono.map(data -> data + " " + ctx.get("lastName"))
)
.contextWrite(context -> context.put("lastName", "Jobs"))
.contextWrite(context -> context.put("firstName", "Steve"))
.subscribe(data -> log.info("# onNext: {}", data));
Thread.sleep(100L);
/*
19:58:52.925 [boundedElastic-1] INFO - # just doOnNext : Hello Steve
19:58:52.934 [parallel-1] INFO - # onNext: Hello Steve Jobs
*/
deferContextual()
transformDeferredContextual()
Operator를 사용해서 Operator 체인 중간에서 데이터를 읽을 수 있다.contextWrite()
Operator를 사용해서 Context에 데이터 쓰기 작업을 할 수 있다.context.readOnly()
final String key1 = "company";
Mono<String> mono = Mono.deferContextual(ctx ->
Mono.just("Company: " + " " + ctx.get(key1))
)
.publishOn(Schedulers.parallel());
mono.contextWrite(context -> context.put(key1, "Apple"))
.subscribe(data -> log.info("# subscribe1 onNext: {}", data));
mono.contextWrite(context -> context.put(key1, "Microsoft"))
.subscribe(data -> log.info("# subscribe2 onNext: {}", data));
Thread.sleep(100L);
/*
20:23:45.821 [parallel-2] INFO - # subscribe2 onNext: Company: Microsoft
20:23:45.821 [parallel-1] INFO - # subscribe1 onNext: Company: Apple
*/
contextWrtie()
Operator가 저장한 값으로 덮어 쓴다.contextWrite()
는 Operator 체인의 맨 마지막에 둡니다!String key1 = "company";
String key2 = "name";
Mono
.deferContextual(ctx ->
Mono.just(ctx.get(key1))
)
.publishOn(Schedulers.parallel())
.contextWrite(context -> context.put(key2, "Bill"))
.transformDeferredContextual((mono, ctx) ->
mono.map(data -> data + ", " + ctx.getOrDefault(key2, "Steve"))
)
.contextWrite(context -> context.put(key1, "Apple"))
.subscribe(data -> log.info("# onNext: {}", data));
Thread.sleep(100L);
/*
20:29:50.870 [parallel-1] INFO - # onNext: Apple, Steve
*/
String key1 = "company";
Mono
.just("Steve")
// .transformDeferredContextual((stringMono, ctx) ->
// ctx.get("role")) // 주석 제거시, 에러 발생
.flatMap(name ->
Mono.deferContextual(ctx ->
Mono
.just(ctx.get(key1) + ", " + name)
.transformDeferredContextual((mono, innerCtx) ->
mono.map(data -> data + ", " + innerCtx.get("role"))
)
.contextWrite(context -> context.put("role", "CEO"))
)
)
.publishOn(Schedulers.parallel())
.contextWrite(context -> context.put(key1, "Apple"))
.subscribe(data -> log.info("# onNext: {}", data));
Thread.sleep(100L);
/*
20:55:24.846 [parallel-1] INFO - # onNext: Apple, Steve, CEO
*/