2017-08-15 154 views
0

我有一种类型的可以提供数据和注册表的不同数据提供者注册的类。我正在寻找一种优雅的方式来实现这一点在春季启动。 我当前的实现看起来像这样(代码缩短为简洁起见):获取特定类型的豆列表

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 { ... } 

现在的布线部分,这就是我想改变的东西更优雅的部分:

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

然后我可以将注册表注入其他需要使用这些服务的类中。

我知道DI是为单一类型提供不同的实现,但一次只能提供一种类型。所以DI最可能不是正确的工具,我的问题更多的是关于春天,如果有一个我不知道实现这个目标的好方法。 作为示例使用限定符对它们进行注释,然后在注册表中使用该限定符解析所有Beans。

我不想采取的方式是使用自定义注释,然后通过反射解析所有类,实例化它们并将它们放入注册表中。但目前,这是我能看到的唯一方法,所以我不必修改配置并手动传送这些服务。

+0

定义什么是“优雅”对你意味着什么?还有其他一些方法可以做到这一点,但我不知道优雅的解决方案对您意味着什么。你希望自动注册所有的提供商还是想要控制它? –

回答

0

如果您希望所有这些都是自动装配的,您可以自动装载您的接口实现列表。

@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(){ ... } 
} 

如果您想使用配置类,你可以这样做,以保持:

@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); 
    } 
} 
+0

这就是我一直在寻找的。我真的有一个脑子结。我想也许你可以autowire列表,但后来认为“不可以,因为这将意味着声明多个相同类型的豆,DI无法处理”,但它当然只是一个问题,如果他们是同一班,不合格,但没有与接口....谢谢 – Tom