Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Gavin King committed Nov 10, 2009
1 parent 96656f2 commit 15910ca
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 33 deletions.
51 changes: 20 additions & 31 deletions reference/en-US/events.xml
Expand Up @@ -93,7 +93,7 @@ public @interface Updated {}]]></programlisting>

<para>
Event producers fire events using an instance of the parameterized <literal>Event</literal> interface.
An instance of this interface are obtained by injection:
An instance of this interface is obtained by injection:
</para>

<programlisting role="JAVA"><![CDATA[@Inject @Any Event<Document> documentEvent;]]></programlisting>
Expand Down Expand Up @@ -126,27 +126,27 @@ public @interface Updated {}]]></programlisting>
</para>

<para>
Qualifiers can be applied to an event type in one of two ways:
Qualifiers can be applied to an event in one of two ways:
</para>

<itemizedlist>
<listitem>
<para>Add qualifier annotations to the field where <literal>Event</literal> is injected or</para>
<para>by annotating the <literal>Event</literal> injection point, or</para>
</listitem>
<listitem>
<para>pass qualifier annotation literals to the <literal>select()</literal> of <literal>Event</literal>.</para>
<para>by passing qualifiers to the <literal>select()</literal> of <literal>Event</literal>.</para>
</listitem>
</itemizedlist>

<para>
The first option is the simplest:
Specifying the qualifiers at the injection point is far simpler:
</para>

<programlisting role="JAVA"><![CDATA[@Inject @Updated Event<Document> documentUpdatedEvent;]]></programlisting>

<para>
Then, every event fired via this instance of <literal>Event</literal> has the event qualifier
<literal>@Updated</literal>. The event will be delivered to every observer method that:
<literal>@Updated</literal>. The event is delivered to every observer method that:
</para>

<itemizedlist>
Expand All @@ -162,27 +162,17 @@ public @interface Updated {}]]></programlisting>
</itemizedlist>

<para>
The downside of annotating the injection point is that you can not specify the qualifiers dynamically.
Fortunately, CDI provides an alternative way of generating derived <literal>Event</literal> instances
from an <literal>Event</literal> instance using the <literal>select()</literal> method and passing
in qualifier annotation literals. Events can then be fired from that narrower source:
The downside of annotating the injection point is that we can't specify the qualifier dynamically. CDI
lets us obtain a qualifier instance by subclassing the helper class <literal>AnnotationLiteral</literal>.
That way, we can pass the qualifier to the <literal>select()</literal> method of <literal>Event</literal>.
</para>

<programlisting role="JAVA"><![CDATA[documentEvent.select(new AnnotationLiteral<Updated>(){}).fire(document);]]></programlisting>

<para>
There is no difference between the firing of this event and the previous one, were the qualifiers were
specified at the injection point. Both events carry the <literal>@Updated</literal> qualifier.
</para>

<para>
As mentioned earlier, the helper class <literal>AnnotationLiteral</literal> makes it possible to instantiate
qualifiers inline, since this is otherwise difficult to do in Java.
</para>

<para>
Event types can have multiple event qualifier types as well, assembled using any combination of annotations
at the injection point and annotations passed to the <literal>select()</literal> method.
Events can have multiple event qualifiers, assembled using any combination of annotations at the
<literal>Event</literal> injection point and qualifier instances passed to the <literal>select()</literal>
method.
</para>

</section>
Expand All @@ -191,21 +181,20 @@ public @interface Updated {}]]></programlisting>
<title>Conditional observer methods</title>

<para>
Normally, observer beans will be "woken up", so to speak, when an event is fired so that they can respond to
the event. This behavior isn't always what you want. You may be interested in delivering an event only to
instances of the observers that exist in one of the currently active contexts.
By default, if there is no instance of an observer in the current context, the container will instantiate the
observer in order to deliver an event to it. This behavior isn't always desirable. We may want to deliver events
only to instances of the observer that already exist in the current contexts.
</para>

<para>
A conditional observer is specified by adding <literal>receive = IF_EXISTS</literal> to the
<literal>@Observes</literal> annotation. The default is to always receive, which means creating
an instance of the bean.
A conditional observer is specified by adding <literal>receive = IF_EXISTS</literal> to the <literal>@Observes</literal>
annotation.
</para>

<programlisting role="JAVA"><![CDATA[public void refreshOnDocumentUpdate(@Observes(receive = IF_EXISTS) @Updated Document d) { ... }]]></programlisting>

<para>
A dependent-scoped bean cannot be a conditional observer, essentially because it's not a contextual bean.
A bean with scope <literal>@Dependent</literal> cannot be a conditional observer, since it would never be called!
</para>

</section>
Expand Down Expand Up @@ -313,8 +302,8 @@ if (document.isBlog()) blogEvent.select(new AnnotationLiteral<Updated>(){}).fire
</itemizedlist>

<para>
Transactional observers are very important in a stateful object model because state is often held for longer
than a single atomic transaction.
Transactional observers are very important in a stateful object model because state is often held for
longer than a single atomic transaction.
</para>

<para>Imagine that we have cached a JPA query result set in the application scope:</para>
Expand Down
22 changes: 20 additions & 2 deletions reference/en-US/injection.xml
Expand Up @@ -526,11 +526,29 @@ public class SynchronousReliablePaymentProcessor implements PaymentProcessor {
<programlisting role="JAVA"><![CDATA[PaymentProcessor p = paymentProcessorSource.get();]]></programlisting>

<para>
Qualifiers can be specified at the injection point:
Qualifiers can be specified in one of two ways:
</para>

<itemizedlist>
<listitem>
<para>by annotating the <literal>Instance</literal> injection point, or</para>
</listitem>
<listitem>
<para>by passing qualifiers to the <literal>select()</literal> of <literal>Event</literal>.</para>
</listitem>
</itemizedlist>

<para>
Specifying the qualifiers at the injection point is much, much easier:
</para>

<programlisting role="JAVA"><![CDATA[@Inject @Asynchronous Instance<PaymentProcessor> paymentProcessorSource;]]></programlisting>


<para>
Now, the <literal>PaymentProcessor</literal> returned by <literal>get()</literal> will have the qualifier
<literal>@Asynchronous</literal>.
</para>

<para>
Alternatively, we can specify the qualifier dynamically. First, we add the <literal>@Any</literal> qualifier to
the injection point, to suppress the default qualifier. (All beans have the qualifier <literal>@Any</literal>.)
Expand Down

0 comments on commit 15910ca

Please sign in to comment.