I know how to implement and use a decorator pattern without Spring.
Because in this pattern you yourself control the process of creating components and you can perform dynamic behavior adding.
Below is an example of implementation without using Spring:
public class SimpleDecoratorApp { public static void main(String[] args) { SimplePrinter simplePrinter = new SimplePrinter(); Printer decorated = new UpperCasePrinterDecorator( new AddAsterisksPrinterDecorator(simplePrinter) ); decorated.print("hello"); // *** HELLO *** } } interface Printer { void print(String msg); } class SimplePrinter implements Printer { @Override public void print(String msg) { System.out.println(msg); } } abstract class PrinterDecorator implements Printer { protected Printer printer; public PrinterDecorator(Printer printer) { this.printer = printer; } } class UpperCasePrinterDecorator extends PrinterDecorator { public UpperCasePrinterDecorator(Printer printer) { super(printer); } @Override public void print(String msg) { String s = msg.toUpperCase(); this.printer.print(s); } } class AddAsterisksPrinterDecorator extends PrinterDecorator { public AddAsterisksPrinterDecorator(Printer printer) { super(printer); } @Override public void print(String msg) { msg = "*** " + msg + " ***"; this.printer.print(msg); } }
I am interested in how to implement the same example but with the help of spring beans.
Because I don’t quite understand how to maintain flexibility in the ability to simply wrap with any number of decorators.
Because as I understand it – it will be implemented fixed in some separate component and I will have to create dozens of various separate components with the combinations of decorators I need.
Advertisement
Answer
I haven’t really understood what is your actual problem here, but I’ll try anyway.
Say you have these classes
UpperCasePrinterDecorator LowerCasePrinterDecorator AddAsterisksPrinterDecorator
Each of these require an instance of a Printer
, which, let’s say is provided as a Spring @Component
. To use each decorator as Spring Bean you need to register it.
@Bean @Qualifier("upperCase") PrinterDecorator upperCasePrinterDecorator(final Printer printer) { // Injected automatically return new UpperCasePrinterDecorator(printer); } @Bean @Qualifier("lowerCase") PrinterDecorator lowerCasePrinterDecorator(final Printer printer) { return new LoweCasePrinterDecorator(printer); } @Bean @Qualifier("asterisk") PrinterDecorator addAsterisksPrinterDecorator(final Printer printer) { return new AddAsterisksPrinterDecorator(printer); }
You can then use the @Qualifier
annotation to get the right one @Autowired
@Autowired @Qualifier("lowerCase") private PrinterDecorator printer;