Cobra's Creations Cobra's Creations - 1 month ago 8
YAML Question

Spring Boot YML Config Class Inheritance

Is it possible to use inheritance in Spring Boot YML configuration classes? If so, how would that be accomplished?

For example:

@ConfigurationProperties(prefix="my-config")
public class Config {
List<Vehicle> vehicles;
}


And the class (or interface) "Vehicle" has two implementations: Truck and Car. So the YAML might look like:

my.config.vehicles:
-
type: car
seats: 3
-
type: truck
axles: 3

Answer

I do not think it is possible (at least not that I know of). You could however design your code as follow:

Inject the properties into a Builder object

Define an object with all properties, which we'll call the VehicleBuilder (or factory, you choose its name). The VehicleBuilders are injected from the Yaml. You can then retrieve each builder's vehicle in a @PostConstruct block. The code:

@ConfigurationProperties(prefix="my-config")
@Component
public class Config {
    private List<VehicleBuilder> vehicles = new ArrayList<VehicleBuilder>();
    private List<Vehicle> concreteVehicles;

    public List<VehicleFactory> getVehicles() {
        return vehicles;
    }

    public List<Vehicle> getConcreteVehicle() {
        return concreteVehicles;
    }

    @PostConstruct
    protected void postConstruct(){
        concreteVehicles = vehicles.stream().map(f -> f.get())
                                   .collect(Collectors.<Vehicle>toList());
    }
}

The builder:

public class VehicleBuilder {
    private String type;
    private int seats;
    private int axles;

    public Vehicle get() {
        if ("car".equals(type)) {
            return new Car(seats);
        } else if ("truck".equals(type)) {
            return new Trunk(axles);
        }
        throw new AssertionError();
    }

    public void setType(String type) {
        this.type = type;
    }

    public void setSeats(int seats) {
        this.seats = seats;
    }

    public void setAxles(int axles) {
        this.axles = axles;
    }
}