我们有一个Spring Boot Restful API,它需要从2个不同的Elasticsearch实例(在不同的服务器上)获取数据,1个用于“共享”数据(其上有大约5个不同的索引),1个用于“私有”数据(带有约3个不同的索引)。目前仅针对“私有”数据实例运行,一切都很好。但我们现在需要获取“共享”数据。
在我们的Spring Boot应用程序中,我们启用了像这样的Elasticsearch存储库
@SpringBootApplication
@EnableElasticsearchRepositories(basePackages = {
"com.company.core.repositories", //<- private repos here...
"com.company.api.repositories" //<-- shared repos here...
})
public class Application { //... }
然后我们使用ElasticsearchRepository访问“私有”数据,如:
package com.company.core.repositories
public interface DocRepository extends ElasticsearchRepository<Doc, Integer> { ... }
在我们的终端中,我们有......
@RestController
@CrossOrigin
@RequestMapping("/v2/statuses/")
public class StatusEndpoint {
@Resource
private ElasticsearchTemplate template;
@Autowired
private DocRepository docRepository;
@Autowired
private Validator validator;
//...
}
现在我们要添加另一个存储库,如:
package com.company.api.repositories
public interface LookupRepository extends ElasticsearchRepository<Lookup, Integer> { ... }
然后在我们的API层中,我们将添加一个自动连接的实例...
@Autowired
private LookupRepository lookupRepo;
我们认为我们可以定义多个具有不同名称的Beans,但是我们如何将每个“elasticsearchTemplate”bean与需要它们的不同ElasticsearchRepository实例相关联?另外,我们如何将“私有”bean /配置与
的注入实例相关联@Resource
private ElasticsearchTemplate template;
我们需要在本地使用它吗?
答案 0 :(得分:1)
您可以使用2个唯一的Elasticsearch配置bean和一个@Resource(name="XXX")
注释来解决此问题,以便在StatusEndpoint控制器中注入模板。
如果根据应使用的Elasticsearch集群将存储库隔离到不同的包中,则可以使用@EnableElasticsearchRepositories注释将它们与不同的配置相关联。
例如:
如果你有这些包和类:
com.company.data.repositories.private.YourPrivateRepository
com.company.data.repositories.shared.YourSharedRepository
然后是这些配置:
@Configuration
@EnableElasticsearchRepositories(
basePackages = {"com.company.data.repositories.private"},
elasticsearchTemplateRef = "privateElasticsearchTemplate")
public class PrivateElasticsearchConfiguration {
@Bean(name="privateElasticsearchTemplate")
public ElasticsearchTemplate privateTemplate() {
//code to create connection to private ES cluster
}
}
@Configuration
@EnableElasticsearchRepositories(
basePackages = {"com.company.data.repositories.shared"},
elasticsearchTemplateRef = "sharedElasticsearchTemplate")
public class SharedElasticsearchConfiguration {
@Bean(name="sharedElasticsearchTemplate")
public ElasticsearchTemplate sharedTemplate() {
//code to create connection to shared ES cluster
}
}
由于elasticsearchTemplateRef
注释中的@EnableElasticsearchRepositories
参数,实现存储库的JPA代码将使用指定的模板作为basePackages
列表中的存储库。
对于StatusEndpoint
部分,您只需为@Resource
注释提供正确的模板bean名称。您的StatusEndpoint
将如下所示:
@RestController
@CrossOrigin
@RequestMapping("/v2/statuses/")
public class StatusEndpoint {
@Resource(name="privateElasticsearchTemplate")
private ElasticsearchTemplate template;
@Autowired
private DocRepository docRepository;
@Autowired
private Validator validator;
//...
}
答案 1 :(得分:0)
可能有多种方法可以做到这一点。这是一个利用@Bean
名称和@Resource
名称的名称。
@Configuration
public class MyElasticConfig{
@Bean //this is your private template
public ElasticsearchTemplate template(){
//construct your template
return template;
}
@Bean //this is your public template
public ElasticsearchTemplate publicTemplate(){
//construct your template
return template;
}
}
那么你可以这样得到它们......
@Resource
private ElasticsearchTemplate template;
@Resource
private ElasticsearchTemplate publicTemplate;
或
@Resource(name="template")
private ElasticsearchTemplate anyName;
@Resource(name="publicTemplate")
private ElasticsearchTemplate anyOtherName;
您也可以直接为@Bean
命名,而不是依赖@Bean
的方法名称。
@Bean (name="template")
public ElasticsearchTemplate myPrivateTemplate(){
//construct your template
return template;
}
@Bean (name="publicTemplate")
public ElasticsearchTemplate myPubTemplate(){
//construct your template
return template;
}
查看有关该主题的这些精彩资源。
SPRING INJECTION WITH @RESOURCE, @AUTOWIRED AND @INJECT
Bean Annotation Type
Autowired vs Resource