original object. However, this design should be well documented and clearly implemented to allow
for better maintainability.
The pluggability of decorators declared in the deployment descriptor makes it easy to enable and
disable decorators without recompiling and redeploying. In a hot deployment environment, the
server does not need to be restarted for the changes to the bean.xml to take effect. This makes
it extremely easy to change the behavior of an application in a production environment with no
interruption to service.
Qualii er use provides a i ner grain of control over the execution of decorators than enabling/
disabling them in the bean.xml deployment descriptor. You can use qualii ers to exclude
certain implementations of an interface from being decorated or to apply different decorators to
implementations of the same interface.
A decorator intercepts calls only to certain Java types. It is aware of all the semantics of that
interface and can implement business logic. This makes it perfect for modeling business concerns
that are identii able for a certain interface type.
Decorators are often contrasted with interceptors. Interceptors intercept invocations of any Java
type, but they are not semantically aware and therefore are not a suitable tool for modeling business
concerns. Interceptors are used to implement cross‐cutting concerns such as logging, security, and
auditing that are not related to business logic.
The heavy use of decorators may introduce runtime bugs, a harder‐to‐understand code base, and a
loss to the advantage of strongly typed static polymorphism. It may also introduce additional test
cases. However, decorators can provide almost unlimited extensibility and a great interface for
future implementations without breaking old code.
In this chapter, you have seen how the implementation of the decorator pattern in Java EE is almost
unrecognizable from its pre‐Java EE ancestor. The object to be decorated is instantiated and injected
by the container, and the decorators to be applied are determined by declarations made in the
bean.xml deployment descriptor or via the strategic use of custom qualii ers.
The use of annotations and dependency injection has reduced the number of lines of code you must
produce to implement a decorator solution and made it easier to introduce additional new classes,
which are automatically decorated by virtue of the interface they implement.
You have seen how the decorator pattern has evolved into what is effectively a pluggable pattern that
can be enabled and disabled while the application is in production with no loss to service. However,
it maintains its original design principle of adding behavior or responsibilities to the objects it