/java/

Using Decorators in CDI Applications

2015-07-16 23:05:51

From docs: Decorators are outwardly similar to interceptors. However, they actually perform tasks complementary to those performed by interceptors. Interceptors perform cross-cutting tasks associated with method invocation and with the lifecycles of beans, but cannot perform any business logic. Decorators, on the other hand, do perform business logic by intercepting business methods of beans. This means that instead of being reusable for different kinds of applications, as are interceptors, their logic is specific to a particular application.

Let's assume that we have interface

package pl.btbw;

public interface Shop {

    String name(int id);

    String type(int id);
}

with implementation:

package pl.btbw;

public class RedShop implements Shop {

    public String name(int id) {
        return "red shop, name with id:" + id;
    }

    public String type(int id) {
        return "red shop, type with id:" + id;
    }
}

and we want to overridden one method.

We can do that by decorator.

First we have to create decorator:

package pl.btbw;

import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.enterprise.inject.Any;
import javax.inject.Inject;

@Decorator
public abstract class ShopDecorator implements Shop {

    @Inject
    @Delegate
    @Any
    private Shop shop;

    public String name(int id) {
        return "decorator: {" + shop.name(id) + "}";
    }
}

pay attention, that decorator class is abstract so we don't need to define all methods form interface

Next, we have to add decorator definition to beans.xml

<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?>

<beans beans_1_0.xsd&quot;="" http:="" java.sun.com="" javaee="" ns="" xml="" xmlns='"http://java.sun.com/xml/ns/javaee"' xmlns:xsi='"http://www.w3.org/2001/XMLSchema-instance"' xsi:schemalocation='"http://java.sun.com/xml/ns/javaee'>
<decorators>
<class>pl.btbw.ShopDecorator</class>
</decorators>
</beans>

Now, if we use somewhere @Inject private Shop shop; and we will execute methods:

System.out.println("name: " + shop.name(97));
System.out.println("type: " + shop.type(97));

the result will be:

&gt; INFO  [stdout] (default task-42) name: decorator: {red shop, name with id:97}
&gt; INFO  [stdout] (default task-42) type: red shop, type with id:97

Github