官术网_书友最值得收藏!

Events

CDI events globally provide an event BUS inside the application. They can be synchronous or asynchronous. To let you have an idea, here is what the code can look like:

@ApplicationScoped
public class LifecycleManager {
@Inject
private Event<Starting> startingEvent;

public void starting() {
final Starting event = new Starting();

startingEvent.fire(event);
startingEvent.fireAsync(event);
}
}

As both types of invocations are exclusive, what we can note here is that these snippets call fire() and fireAsync(). To be able to target all the observers, you need to invoke both. This means that the associated logic will be twice.

Without entering into the details that do not impact our performance, both cases share the same resolution mechanism:

  1. Resolve the observers based on the event type.
  2. Remove the observers not matching the fire type (asynchronous or synchronous).
  3. Sort the observers by priority.
  4. Handle the invocations.

The difference between synchronous and asynchronous cases is point 4. In the synchronous case, it just means, invoke the observers, whereas in the asynchronous case, it means, call asynchronously and return CompletionStage representing all the invocation results.

The parts impacting the performance are the resolution of the observers and the invocation, which can require some bean resolution.

We already saw bean resolution, so let's dig into the observer resolution here. Indeed, the implementation is specific to the vendor you are using. But, as it is impossible to use static analysis to implement this part, the resolution is done at runtime with a cache per event type. Note that the caching depends a lot on the implementation. Most will only cache raw type events.

This concretely means that the invocation without generics, as shown in the following code, will be way faster than the invocation that implements generics and enforces the CDI container to do some more resolution:

event.fire(new MyEvent());

In terms of the code, and to let you compare it with the previous example, the code with generics would be exactly the same except the event would be parameterized:

event.fire(new MyEvent<String>());

Then, once you have the potential set of observers, you need to reduce the set based on the qualifiers that the caller configures for the event. This also implies some reflection, more or less cached, depending on the implementation.

Finally, some runtime checks are enforced by the set of tests that the vendors have to pass so that we can claim to be compliant with the specifications.

All these steps are more or less optimized by vendors depending on the cases they may have received complaints about. But in all of them, you can end up on code paths where everything is done at runtime for the firing of each event, which can be a pain in terms of the performance.

主站蜘蛛池模板: 遵化市| 淮安市| 太湖县| 延吉市| 望都县| 马关县| 嘉黎县| 社会| 昭平县| 高邑县| 高邑县| 女性| 昔阳县| 大埔县| 盐池县| 五指山市| 湖南省| 云梦县| 塔城市| 商丘市| 建昌县| 温宿县| 海口市| 涞源县| 班玛县| 广元市| 涿鹿县| 封开县| 延庆县| 黑山县| 延长县| 水富县| 长宁区| 兖州市| 迭部县| 威远县| 中宁县| 鹰潭市| 师宗县| 南宁市| 梅河口市|