简体   繁体   中英

Get a List of Beans for a certain type

I have a certain type of class that can provide data and a registry where the different data providers are registered. I am looking for an elegant way to implement this in spring boot. My current implementation looks like this (code is shortened for brevity):

public interface DataProvider{
    Data getSomeData();
}

public class Registry{
    public register(DataProvider provider){
       //add to internal list
    };

    public List<DataProvider> getProviders(){
       //return providers
    }

    public Data someAggregatedOperation(){ ... }
}

public class Provider1 implements DataProvider { ... }

public class Provider2 implements DataProvider { ... }

Now for the wiring part, and this is the part I want to change to something more elegant:

@Configuration
public class MyAppConfiguration{
    @Bean 
    public Registry providerRegistry(){
        Registry reg = new Registry();
        reg.register(new Provider1());
        reg.register(new Provider2());
        return reg;
    }
}

Then I can inject the registry into other classes that need to operate on the services.

I know that DI is for providing different implementation for a single type but one at a time. So DI most probably is not the right tool, my question is more about spring if there's a good way I don't know to achieve this. As example Annotate them with a Qualifier and then resolve all Beans with that qualifier in the registry.

The way I would not want to take is using a custom Annotation and then resolving all the classes via reflection, instantiate them and put them in the registry. But at the moment it's the only way I can see so I don't have to modify the config and handwire the services.

If you want all of them to be autowired, you can just autowire a list of your interface implementations.

@Bean
public class Provider1 implements DataProvider { ... }

@Bean
public class Provider2 implements DataProvider { ... }

@Bean
public class Registry{
    @Autowired
    private List<DataProvider> providers;

    public List<DataProvider> getProviders(){
       //return providers
    }

    public Data someAggregatedOperation(){ ... }
}

In case you want to keep using a configuration class you could do something like:

@Bean
public class Provider1 implements DataProvider { ... }

@Bean
public class Provider2 implements DataProvider { ... }

public class Registry{
    private List<DataProvider> providers;

    public Registry(final List<DataProvider> providers) {
      this.providers = providers;
    }

    public List<DataProvider> getProviders(){
       //return providers
    }

    public Data someAggregatedOperation(){ ... }
}

@Configuration
public class MyAppConfiguration{

    @Bean
    @Autowired
    public Registry providerRegistry(final List<DataProvider> providers){
        return new Registry(providers);
    }
}

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