简体   繁体   中英

Spring create list of beans based on properties

In a simple Spring boot application I have my component like this:

@Data
@Component
public class GenericHandler {
    private String path;
    private HandlerType type;
}

And my properties might look like this:

my.handlers[0].path='/vol1/abc'
my.handlers[0].type='Single'
my.handlers[1].path='/vol1/dora'
my.handlers[1].type='MultiSequence'

I tried decorating with the GenericHandler-class with @ConfigurationProperties(prefix="my.handlers") and getting a list of all component instances in a service using

@Autowired
private List<GenericHandler> handlers;

But that created just one component, ignoring the property values at all.

How can I get one component instance per my.handlers property-entry?

  • You need a wrapper class
    @Component
    @ConfigurationProperties(prefix="my.handlers")
    @Data
    public class GenericHandlerWrapper {

      private List<GenericHandler> handlers;
      ...

    }
  • Then you can autowire the GenericHandlerWrapper

Update

  • As @zoolway pointed out in the comments, for the properties in the question to work as it is, @ConfigurationProperties(prefix="my.handlers") should be changed to @ConfigurationProperties(prefix="my")

That's not possible. What can be done is this:

@Data
@Component
public class GenericHandler {
    private List<String> path;
    private List<HandlerType> type;
}

I dealt with a similar issue in a different manner. I created a factory and an interface. The factory would hold different implementations of that interface In your case, GenericHandler would be your interface. Then you write any number of implementations of your interface and each implementation is declared as a Component. So, Spring will instantiate it as bean upon a startup (you might use @Lazy(false) to force the instantiation at startup) using some infrastructure that I wrote each bean of that interface will self-insert itself into its factory. Then at any part of your code in any bean, you can use the factory to access concrete implementation (base on your property "type" for example). The beauty is that you don't need to inject all the implementations in your bean at the time of writing but access needed implementation dynamically at run-time. I found this to be a useful pattern and created an infrastructure that does most of the work for you and published it as an Open Source library called MgntUtils. The detailed description of the idea (including reference to the library) could be found here . Also detailed explanation with examples of how to use it can be found in library Javadoc here . The library is available (with source code and Javadoc) as Maven artifacts and on the Github . Also a general article about the MgntUtils library could be found here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM