© DrHitch/Shutterstock.com
Shortcuts
CDI

11 Decorators


Ein Decorator ähnelt in seiner Funktion einem Interceptor: Er wird auch in den Aufrufweg eingeschleust, kann also die Semantik von Bean-Methoden nahezu beliebig verändern. Anders als ein Interceptor implementiert der Decorator aber ein fachliches Interface, wodurch er sich gut für die Modifikation fachlicher Logik eignet.

Decorator Class

Ein Decorator ist eine Klasse, die mit @Decorator (javax.decorator.Decorator) annotiert ist und einen Bean Type implementiert. Zudem benötigt der Decorator genau einen Injektionspunkt für sein Delegate, d. h. für das Objekt, das er dekoriert, auf dessen Funktionalität sich sein Code abstützt. Dieser Injektionspunkt muss mit @Delegate (javax.decorator.Delegate) annotiert sein. Es kann sich dabei um ein Feld, einen Methodenparameter oder einen Konstruktorparameter handeln (Listing 11.1).

@Decorator
public abstract class NonAlcoholicCocktailRepository
implements CocktailRepository
{
@Inject @Delegate @Any
private CocktailRepository cocktailRepository
;

public List<Cocktail> findAll()
{
List<Cocktail> result = this.cocktailRepository.findAll();

Iterator<Cocktail> iterator = result.iterator();
while (iterator.hasNext())
{
Cocktail cocktail = iterator.next();
if (cocktail.isAlcoholic())
iterator.remove();
}

return result;
}
}

Listing 11.1: Decorator

Der Injektionspunkt für das Delegate bestimmt, für welche CDI Beans der Decorator eingesetzt wird, nämlich genau diejenigen, die mindestens die Qualifier des Delegates haben. Im Beispiel steht der Decorator also für alle Beans des Typs CocktailRepository zur Verfügung, unabhängig von ihren restlichen Qualifiern. Würde man @Any weglassen, wäre der Decorator nur für @Default-CocktailRepositories zuständig.

Der Decorator darf abstract sein, muss somit auch nicht alle Methoden des dekorierten Interfaces implementieren. Die restlichen Methoden werden dann durch direkten Aufruf des dekorierten Objekts aufgelöst. Mit dem gezeigten Beispiel wird also nur die Funktion der findAll-Methode verändert. Aufrufe der anderen Methoden aus CocktailRepository werden direkt zum Delegate durchgeleitet.

Die dekorierte Version im Beispiel entfernt übrigens die alkoholischen Drinks aus der Ergebnisliste, sodass Sie nun erst recht weiterlesen sollten, selbst wenn Sie alkoholische Beispiele für moralisch grenzwertig halten.

Aktivierung eines Decorators

Analog zu einem Interceptor muss auch ein Decorator im Deskriptor beans.xml eingetragen werden, wenn er aktiv sein soll. Das zugehörige Element ist <decorators> (...

Shortcuts
CDI

11 Decorators

Ein Decorator ähnelt in seiner Funktion einem Interceptor: Er wird auch in den Aufrufweg eingeschleust, kann also die Semantik von Bean-Methoden nahezu beliebig verändern. Anders als ein Interceptor implementiert der Decorator aber ein fachliches Interface, wodurch er sich gut für die Modifikation fachlicher Logik eignet.

Shortcut Autorenteam


Ein Decorator ähnelt in seiner Funktion einem Interceptor: Er wird auch in den Aufrufweg eingeschleust, kann also die Semantik von Bean-Methoden nahezu beliebig verändern. Anders als ein Interceptor implementiert der Decorator aber ein fachliches Interface, wodurch er sich gut für die Modifikation fachlicher Logik eignet.

Decorator Class

Ein Decorator ist eine Klasse, die mit @Decorator (javax.decorator.Decorator) annotiert ist und einen Bean Type implementiert. Zudem benötigt der Decorator genau einen Injektionspunkt für sein Delegate, d. h. für das Objekt, das er dekoriert, auf dessen Funktionalität sich sein Code abstützt. Dieser Injektionspunkt muss mit @Delegate (javax.decorator.Delegate) annotiert sein. Es kann sich dabei um ein Feld, einen Methodenparameter oder einen Konstruktorparameter handeln (Listing 11.1).

@Decorator
public abstract class NonAlcoholicCocktailRepository
implements CocktailRepository
{
@Inject @Delegate @Any
private CocktailRepository cocktailRepository
;

public List<Cocktail> findAll()
{
List<Cocktail> result = this.cocktailRepository.findAll();

Iterator<Cocktail> iterator = result.iterator();
while (iterator.hasNext())
{
Cocktail cocktail = iterator.next();
if (cocktail.isAlcoholic())
iterator.remove();
}

return result;
}
}

Listing 11.1: Decorator

Der Injektionspunkt für das Delegate bestimmt, für welche CDI Beans der Decorator eingesetzt wird, nämlich genau diejenigen, die mindestens die Qualifier des Delegates haben. Im Beispiel steht der Decorator also für alle Beans des Typs CocktailRepository zur Verfügung, unabhängig von ihren restlichen Qualifiern. Würde man @Any weglassen, wäre der Decorator nur für @Default-CocktailRepositories zuständig.

Der Decorator darf abstract sein, muss somit auch nicht alle Methoden des dekorierten Interfaces implementieren. Die restlichen Methoden werden dann durch direkten Aufruf des dekorierten Objekts aufgelöst. Mit dem gezeigten Beispiel wird also nur die Funktion der findAll-Methode verändert. Aufrufe der anderen Methoden aus CocktailRepository werden direkt zum Delegate durchgeleitet.

Die dekorierte Version im Beispiel entfernt übrigens die alkoholischen Drinks aus der Ergebnisliste, sodass Sie nun erst recht weiterlesen sollten, selbst wenn Sie alkoholische Beispiele für moralisch grenzwertig halten.

Aktivierung eines Decorators

Analog zu einem Interceptor muss auch ein Decorator im Deskriptor beans.xml eingetragen werden, wenn er aktiv sein soll. Das zugehörige Element ist <decorators> (...

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang