Spring:实现一个@Service的两个实例,其中两个@Configuration实例链接到每个相应的服务



存在一个我正在导入到项目中的现有实用程序。它的编写与这两个类类似

@Service
public class ServiceAccessorImpl implements ServiceAccessor {
@Autowired private ServiceConfiguration serviceConfiguration;
public Response executeCall(){
return callEndPoint(serviceConfiguration.getServiceEndPoint());
}
}
@Configuration
@Data //automatically adds getters and setters
@ConfigurationProperties(prefix="config")//pulls serviceEndPoint value from external config
//Assume external config has config.serviceEndPoint = "www.endpoint1.com"
public class ServiceConfiguration {
private String serviceEndPoint;
}

在下面的一个单独的项目中,我将上述内容导入到我的项目中。我希望同一服务的两个实例具有两个唯一且各自的配置类。使得服务1被链接到config1并且服务2被链接到configuration2。我的理由是,我想要一个只从外部配置中提取端点的实例,以及另一个可以用来设置端点的实例。我尝试过使用@Qualifier之类的东西,但我不知道如何将正确的配置与正确的服务联系起来。我有一种感觉,这可能是不可能的,因为ServiceConfiguration是ServiceAccessorImpl中的私有范围,我无法通过setter或构造函数进行访问。

控制器终结点。下面是我想如何实现我的设计的psuedo代码。在单个实例中自动布线并使用任一端点适用于该端点,但不适用于两者,如下所示。

@ComponentScan(basePackageClass = ServiceAccessorImpl.class)
public class ServiceAccessorController {

@Autowired private ServiceAccessor serviceAccessor1;
@Autowired private ServiceConfiguration serviceConfiguration1;
@Autowired private ServiceAccessor serviceAccessor2;
@Autowired private ServiceConfiguration serviceConfiguration2;
Response CallEndpoint1(){
//www.endpoint1.com is already set here from external config
return serviceAccessor1.executeCall();
}

Response CallEndpoint1(){
serviceConfiguration2.setServiceEndPoint("www.endpoint2.com")
return serviceAccessor2.executeCall();
}
}

提前感谢

如果您需要同一实现的多个实例,则更容易不将其注释为bean,而是由@Configuration提供bean。

public class ServiceAccessorImpl implements ServiceAccessor {
private ServiceConfiguration serviceConfiguration;
public ServiceAccessorImpl(ServiceConfiguration configuration) {
this.serviceConfiguration = configuration;
}
public Response executeCall(){
return callEndPoint(serviceConfiguration.getServiceEndPoint());
}
}
// this one should just have @ConfigurationProperties, not @Configuration
@Data
@ConfigurationProperties(prefix="config")
public class ServiceConfiguration {
private String serviceEndPoint;
}

然后在你的服务中,你可以有一个提供两个实例的配置:

@Configuration
public class BeansConfiguration {

@Qualifier("service1")
@Primary // optional, Spring will autowire this instance by default if no qualifier is given
@Bean
public service1(@Autowired ServiceConfiguration config) {
// use the default config bean
return new ServiceAccessorImpl(config);
}
@Qualifier("service2")
@Bean
public service2() {
return new ServiceAccessorImpl(new ServiceConfiguration("www.endpoint2.com"));
}
}

然后您可以通过使用限定符来消耗这两个(注意,您不必在此处注入配置(:

public class ServiceAccessorController {

@Autowired
private ServiceAccessor serviceAccessor1;
@Autowired 
@Qualifier("service2")
private ServiceAccessor serviceAccessor2;
Response CallEndpoint1(){
return serviceAccessor1.executeCall();
}

Response CallEndpoint2(){
return serviceAccessor2.executeCall();
}
}

最新更新