私の春ブーツアプリでは私が持っている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
// ...
}
}
私は、クライアントにこれらのゲートウェイを公開するが、1つのゲートウェイは、1つのクライアントだけのクラス(クライアントAまたはclientB)に慣れるようにしたいです。
そのために、私は彼らが提供するIDに基づいて、ゲートウェイへのクライアントの実装をマッピングするためにマッパークラスwritteanています。
@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;
}
}
どのように私は、クライアントAとclientBが同じゲートウェイIDを使用しないように制限する必要があります。彼らはすべてのゲートウェイを使用することを許可されているが、彼らは同じゲートウェイを使用しないでください。またはゲートウェイとクライアントAまたはclientBをマップするため、他のより良い方法があります
ID /ゲートウェイが既に使用されている場合は、コンパイル時には、これらのクラスのクライアントは知ることができません。
あなたは、クライアントのオブジェクトへのゲートウェイを関連付ける場合にのみ、実行時に発見することができます。
@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を宣言するクライアント用の新しいゲートウェイを再割り当てすることができます回避。
ゲートウェイとクライアントAまたはclientBをマップするため、他のより良い方法はあります
クライアントが直接AAゲートウェイに接続されたが、代わりにサーバーを関連付けるクライアント彼らの要件に合致するものをゲートウェイにされていませんはい方法。
アイデアは、サーバ側でのゲートウェイのプールを提供しています。
クライアント側からは、クライアントではなく、彼らはすべてが、ゲートウェイ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();
}