Skip to content
Advertisement

How to implement Decorator pattern in Spring Boot

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;

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement