Reactive CDI

Reactive utilities for CDI and Java >= 11.

License

License

Categories

Categories

React User Interface Web Frameworks
GroupId

GroupId

com.github.rmannibucau.reactive
ArtifactId

ArtifactId

reactive-cdi
Last Version

Last Version

1.0.5
Release Date

Release Date

Type

Type

pom
Description

Description

Reactive CDI
Reactive utilities for CDI and Java >= 11.
Project URL

Project URL

https://github.com/rmannibucau/reactive-cdi
Source Code Management

Source Code Management

https://github.com/rmannibucau/reactive-cdi.git

Download reactive-cdi

Filename Size
reactive-cdi-1.0.5.pom 5 KB
Browse

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.rmannibucau.reactive/reactive-cdi/ -->
<dependency>
    <groupId>com.github.rmannibucau.reactive</groupId>
    <artifactId>reactive-cdi</artifactId>
    <version>1.0.5</version>
    <type>pom</type>
</dependency>
// https://jarcasting.com/artifacts/com.github.rmannibucau.reactive/reactive-cdi/
implementation 'com.github.rmannibucau.reactive:reactive-cdi:1.0.5'
// https://jarcasting.com/artifacts/com.github.rmannibucau.reactive/reactive-cdi/
implementation ("com.github.rmannibucau.reactive:reactive-cdi:1.0.5")
'com.github.rmannibucau.reactive:reactive-cdi:pom:1.0.5'
<dependency org="com.github.rmannibucau.reactive" name="reactive-cdi" rev="1.0.5">
  <artifact name="reactive-cdi" type="pom" />
</dependency>
@Grapes(
@Grab(group='com.github.rmannibucau.reactive', module='reactive-cdi', version='1.0.5')
)
libraryDependencies += "com.github.rmannibucau.reactive" % "reactive-cdi" % "1.0.5"
[com.github.rmannibucau.reactive/reactive-cdi "1.0.5"]

Dependencies

provided (1)

Group / Artifact Type Version
org.apache.meecrowave : meecrowave-specs-api jar 1.2.10

test (2)

Group / Artifact Type Version
org.junit.jupiter : junit-jupiter jar 5.7.0
org.apache.meecrowave : meecrowave-junit jar 1.2.10

Project Modules

  • reactive-cdi-scope
  • reactive-servlet

Reactive CDI

A set of small modules to help using CDI in reactive context.

Scope, a.k.a. ReactiveScoped

Reactive scope enables to put in reactive context bean instances. It is defined with @ReactiveScoped scope annotation:

@ReactiveScoped
public class MyService {}

The definition of the scope is handled thanks to ReactiveContext. The instance to use can be injected as any bean:

@Inject
private ReactiveContext context;

It must be:

  1. Started thanks to var ctx = context.start();: it initializes a new reactive context which beans new bean instances (for a new request or exchange for ex.).

  2. Each thread it is used in must be resetted once it is no more needed: context.reset(previousContextSnapshot);: it restores the previous context - delete it if there was no previous context.

  3. When no more needed by any thread it must be destroyed with context.finish(ctx): it destroys the contextual for the ctx bean instances.

The propagation is done thanks to ReactiveContext.Ctx methods. The easiest is to use wrap() methods which wrap Runnable or Supplier in a context aware instance:

final Runnable myTask = () -> {...};

final var ctx = reactiveContext.current();
final Runnable wrapped = ctx.wrapExecutor(myTask);
threadPool.submit(wrapped); // will be executed in the reactive context of the caller

Executor and ExecutorService

The ReactiveContext provides wrap* methods for executors and executor services enabling to quickly make a thread pool reactive friendly.

CompletionStage

The ReactiveContext provides wrap* methods for completion stages and futures.

Warning
however, this wrapping is limited to synchronous callbacks and not Async flavors. For such cases, the executor wrapping will be needed too.

Servlet integration

Servlet integration is done with a Filter you have to position in your filter chain where you want to start the reactive context. This filter class is com.github.rmannibucau.reactive.cdi.servlet.RootReactiveContextFilter. It is async friendly, i.e. if you use AsyncContext of servlet specification, it will make its start() method reactive aware and the automatically started reactive scope will be destroyed at the end of the request (asynchronous or not).

To register the filter, you can use web.xml registration, ServletContainerInitializer or any other way. Another simple solution is to subclass the filter to register it:

@Dependent
@WebFilter(urlPatterns = "/*", asyncSupported = true)
public class Register extends RootReactiveContextFilter {}

Versions

Version
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0