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

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.

主站蜘蛛池模板: 斗六市| 泰宁县| 阿瓦提县| 玉龙| 寿阳县| 平罗县| 青岛市| 惠安县| 怀仁县| 响水县| 建湖县| 陵川县| 洛扎县| 萨嘎县| 北川| 陵水| 镇康县| 潢川县| 扬州市| 布拖县| 清水县| 台北市| 屏山县| 高邑县| 福海县| 永寿县| 图们市| 贵定县| 丹棱县| 乐亭县| 疏勒县| 淳安县| 中西区| 博罗县| 卫辉市| 广汉市| 图们市| 德兴市| 湟源县| 庐江县| 璧山县|