Skip to content

Commit

Permalink
revisions
Browse files Browse the repository at this point in the history
  • Loading branch information
Gavin King committed Nov 10, 2009
1 parent b68faa5 commit 58b09aa
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 62 deletions.
113 changes: 57 additions & 56 deletions reference/en-US/decorators.xml
Expand Up @@ -43,75 +43,65 @@

<programlisting role="JAVA"><![CDATA[@Decorator
public abstract class LargeTransactionDecorator
implements Account {
implements Account {
...
}]]></programlisting>

<para>
So what goes in the decorator? Well, decorators have to inject the instance of the bean they are decorating,
termed the <emphasis>delegate injection point</emphasis>. The injection point has the same type as the bean to
decorate and the annotation <literal>@Delegate</literal>. There can be at most one injection point, which can be a
constructor, initializer method or field injection.
</para>

<programlisting role="JAVA"><![CDATA[@Decorator
public abstract class LargeTransactionDecorator
implements Account {
@Inject @Delegate @Any Account account;
...
}]]></programlisting>

<para>
You'll see in a moment that the beans which are decorated can be further restricted by specifying qualifiers at
the injection point, a familiar pattern in CDI.
</para>

<para>
The decorator then implements any methods of the bean type it wants to decorate. The decorator can in turn invoke
the method on the decorated instance. Note that the method on the decorate is being called by the container
<emphasis>instead of</emphasis> the method on the bean instance. It's up to the decorator to invoke the method on
the bean instance. In fact, the decorator can invoke any method on the bean instance.
The decorator implements the methods of the decorated type that it wants to intercept.
</para>

<programlisting role="JAVA"><![CDATA[@Decorator
public abstract class LargeTransactionDecorator
implements Account {
implements Account {
@Inject @Delegate @Any Account account;
@PersistenceContext EntityManager em;
public void withdraw(BigDecimal amount) {
account.withdraw(amount);
if ( amount.compareTo(LARGE_AMOUNT)>0 ) {
em.persist( new LoggedWithdrawl(amount) );
}
}
...
}
public void deposit(BigDecimal amount);
account.deposit(amount);
if ( amount.compareTo(LARGE_AMOUNT)>0 ) {
em.persist( new LoggedDeposit(amount) );
}
...
}
}]]></programlisting>

<para>
Interceptors for a method are called before decorators that apply to that method.
</para>

<para>
Unlike other beans, a decorator may be an abstract class. Therefore, if there's nothing special the decorator
needs to do for a particular method of the decorated interface, you don't need to implement that method.
</para>

<para>
Interceptors for a method are called before decorators that apply to the method.
</para>

<section>
<title>Delegate object</title>

<para>
All decorators must have a delegate injection point that injects the delegate object, as shown above. The type
and qualifier types of the delegate injection point determine which beans the decorator is bound to. The
delegate object type must implement or extend all interfaces implemented by the decorator.
</para>
<para>
Decorators have a special injection point, called the <emphasis>delegate injection point</emphasis>, with the same
type as the beans they decorate, and the annotation <literal>@Delegate</literal>. There must be exactly one delegate
injection point, which can be a constructor parameter, initializer method parameter or injected field.
</para>

<programlisting role="JAVA"><![CDATA[@Decorator
public abstract class LargeTransactionDecorator
implements Account {
@Inject @Delegate @Any Account account;
...
}]]></programlisting>

<para>A decorator is bound to any bean which:</para>

<itemizedlist>
<listitem>
<para>has the type of the delegate injection point as a bean type, and</para>
</listitem>
<listitem>
<para>has all qualifiers that are declared at the delegate injection point.</para>
</listitem>
</itemizedlist>

<para>
This delegate injection point specifies that the decorator is bound to all beans that implement
Expand All @@ -121,29 +111,40 @@ public abstract class LargeTransactionDecorator
<programlisting role="JAVA"><![CDATA[@Inject @Delegate @Any Account account;]]></programlisting>

<para>
A delegate injection point may specify any number of qualifier annotations. Then the decorator will only be
A delegate injection point may specify any number of qualifier annotations. The decorator will only be
bound to beans with the same qualifiers.
</para>

<programlisting role="JAVA"><![CDATA[@Inject @Delegate @Foreign Account account;]]></programlisting>

<para>A decorator is bound to any bean which:</para>

<itemizedlist>
<listitem>
<para>has the type of the delegate object as a bean type, and</para>
</listitem>
<listitem>
<para>has all qualifiers that are declared at the delegate injection point.</para>
</listitem>
</itemizedlist>

<para>
The decorator may invoke the delegate object, which has much the same effect as calling
<literal>InvocationContext.proceed()</literal> from an interceptor. The main difference is that the decorator
can invoke <emphasis>any</emphasis> business method on the delegate object.
</para>

<programlisting role="JAVA"><![CDATA[@Decorator
public abstract class LargeTransactionDecorator
implements Account {
@Inject @Delegate @Any Account account;
@PersistenceContext EntityManager em;
public void withdraw(BigDecimal amount) {
account.withdraw(amount);
if ( amount.compareTo(LARGE_AMOUNT)>0 ) {
em.persist( new LoggedWithdrawl(amount) );
}
}
public void deposit(BigDecimal amount);
account.deposit(amount);
if ( amount.compareTo(LARGE_AMOUNT)>0 ) {
em.persist( new LoggedDeposit(amount) );
}
}
}]]></programlisting>

</section>

<section>
Expand All @@ -167,7 +168,7 @@ public abstract class LargeTransactionDecorator
</beans>]]></programlisting>

<para>
This declaration serves the same purpose for decorators that the <literal>&lt;Interceptors&gt;</literal>
This declaration serves the same purpose for decorators that the <literal>&lt;interceptors&gt;</literal>
declaration serves for interceptors:
</para>

Expand Down
10 changes: 4 additions & 6 deletions reference/en-US/next.xml
Expand Up @@ -5,12 +5,10 @@

<para>
Because CDI is so new, there's not yet a lot of information available online. That will change over time.
Regardless, the CDI specification remains the authority for information on CDI. The spec is kept at around 100
pages intentionally easy to read (don't worry, it's not like your Blue-ray player manual). You may be especially
interested in reading it since it covers many details that we've skipped over. The spec is available on the
<ulink src="http://jcp.org/en/jsr/detail?id=299">JSR-299 page</ulink> at the JCP website. Updates to the spec are
also frequently mailed to the <ulink src="https://lists.jboss.org/mailman/listinfo/weld-dev">weld-dev</ulink>
mailing list.
Regardless, the CDI specification remains the authority for information on CDI. The spec less than 100 pages and
is quite readable (don't worry, it's not like your Blu-ray player manual). Of course, it covers many details we've
skipped over here. The spec is available on the
<ulink src="http://jcp.org/en/jsr/detail?id=299">JSR-299 page</ulink> at the JCP website.
</para>

<para>
Expand Down

0 comments on commit 58b09aa

Please sign in to comment.