在我的 Spring Boot 应用程序中,我有包含以下内容的 application.yml 配置文件
config:
gateways:
-
id: 'g0'
nbrInputs: 128
nbrOutputs: 128
-
id: 'g1'
nbrInputs: 128
nbrOutputs: 128
配置类:
@Configuration
@ConfigurationProperties(prefix="config")
@EnableConfigurationProperties
public class GatewayConfig
{
List<Gateway> gateways = new ArrayList<Gateway>();
public List<Gateway> getGatewayList(){
return gateways;
}
public static class Gateway
{
private String id;
private int nbrInputs;
private int nbrOutputs;
// Getters and Setters
// ...
}
}
我想向客户端公开这些网关,但希望允许一个网关仅用于一个客户端类(clientA 或 clientB)。
为此,我编写了一个 Mapper 类来根据客户端提供的 ID 将客户端实现映射到网关。
@Component
public class MapGatewaytoClasses{
@Autowired
private GatewayConfig gc;
@Autowired
private ApplicationContext ac;
@PostConstruct
public void init(){
List<Gateway> lg = gc.getGatewayList();
Map<String, Object> beans = applicationContext.getBeansWithAnnotation(Myannotation.class);
for (Map.Entry<String,Object> entry : beans.entrySet()) {
for(Gateway g: lg){
Client c = (Client)entry.getValue();
if(c.getId().equalsIgnoreCase(g.getId())){
c.setGateway(g);
}
}
}
}
}
public abstract client{
protected String id;
public String getId() {
return id;
}
}
现在新客户端必须扩展此客户端才能使用。
@Component
@Myannotation
public class clientA extends Client {
Gateway gateway;
public A(){
id="g0";
}
public void setGateway(Gateway gateway){
this.gateway = gateway;
}
}
@Component
@Myannotation
public class clientB extends Client{
Gateway gateway;
public B(){
id="g1";
}
public void setGateway(Gateway gateway){
this.gateway = gateway;
}
}
我应该如何限制 clientA 和 clientB 不使用相同的网关 ID。 他们可以使用任何网关,但不应该使用相同的网关。 或者是否有任何其他更好的方法将 clientA 或 clientB 与网关映射
最佳答案
在编译时,这些类的客户端无法知道 id/gateway 是否已被使用。
当您将网关关联到客户端对象时,它只能在运行时被发现:
@PostConstruct
public void init(){
List<Gateway> lg = gc.getGatewayList();
Map<String, Object> beans = applicationContext.getBeansWithAnnotation(Myannotation.class);
for (Map.Entry<String,Object> entry : beans.entrySet()) {
for(Gateway g: lg){
Client c = (Client)entry.getValue();
if(c.getId().equalsIgnoreCase(g.getId())){
c.setGateway(g);
}
}
}
}
这个时候,已经晚了。因此,作为解决方法,您可以为声明相同网关 ID 的客户端禁用或重新分配一个新网关。
Is there any other better way to map clientA or clientB with gateways
是的,客户端不直接耦合到网关的方式
而是在服务器将客户端关联到满足其要求的网关的地方。
这个想法是在服务器端提供一个网关池。
从客户端来看,客户端不指定他们将使用哪个网关,而是只指定他们对所需网关容量的要求,除了网关 ID 之外的所有内容:
config:
gateways:
-
id: 'g0'
nbrInputs: 128
nbrOutputs: 128
-
id: 'g1'
nbrInputs: 64
nbrOutputs: 64
client-gateway:
-
nbrInputs: 128
nbrOutputs: 128
-
nbrInputs: 64
nbrOutputs: 64
服务器的角色是在运行时为每个声明的需要网关的客户端分配一个网关。
它可能应该在 init()
方法中完成。
这是一个给出想法的例子:
@PostConstruct
public void init(){
Map<String, Object> beans = applicationContext.getBeansWithAnnotation(Myannotation.class);
for (Map.Entry<String,Object> entry : beans.entrySet()) {
Client c = (Client) entry.getValue();
Optional<Gateway> gateway = findMatchingGateway(c);
if (gateway.isPresent()){
c.setGateway(g);
gc.getGatewayList()
.removeIf(o->o.getId()==g.getId())
)
else {
// handle the not found case
}
}
}
}
private Optional<Gateway> findMatchingGateway(Client client){
return
gc.getGatewayList()
.stream()
.filter(g.nbrInputs() == client.getNbrInputs())
.findAny();
}
关于java - 限制客户端仅使用从 yml 文件创建的配置列表中的一个配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57391142/