Hallo Spring Container LevelのBeanファクトリにある別の実装間で、プログラムで候補を選択する方法を探したいと思います。プログラムでのBean注入の解決
プロファイルと私は単にこの
のようにそれを達成することができ、私持っている以下のプロファイルの「CH」と「IT」は、私はそれで豆プロファイル下がある場合は、デフォルトにフォールバックすることを望みます。
を考えると、これらのクラス:
デフォルト実装
@Component
public class DefaultMapper {
public void doSomething() {
System.out.println("Map Default");
}
}
スイス実装
@Component
@Profile("CH")
public class SwissMapper extends DefaultMapper {
@Override
public void doSomething() {
System.out.println("do something swiss");
}
}
イタリアの実装:今
@Component
@Profile("IT")
public class ItalianMapper extends DefaultMapper {
@Override
public void doSomething() {
System.out.println("do pasta");
}
}
私はそれを実行した場合@ActiveProfiles("IT")
とするとNoUniqueBeanDefinitionExceptionがスローされます。これは、Defaultがプロファイルされていないので十分であり、コンテナによってそれ以上の注意を払うことなく登録されます。
考察:
私はDefaultMapper
に@Profile("default")
を追加した場合、私は別のデフォルトBeanがONLY CHでプロファイルサブクラスを持っている持ってまで、これは動作します。
別のBeanのデフォルトの実装:
@Component
@Profile("default")
public class DefaultParser {
public void doSomething() {
System.out.println("Parse Default");
}
}
その後スイスの実装(NOイタリア語が使用できない、またはより良いデフォルトはイタリアのために収まる言った):
今@Component
@Profile("CH")
public class SwissParser extends DefaultParser {
@Override
public void doSomething() {
System.out.println("Ässe Ässe");
}
}
@ActiveProfiles("IT")
を実行するとNo BeanDefinitionExceptionがスローされますが、「デフォルト」がActiveProfilesとしてチェーン化されていないため私は実装がありません。ここでのCHプロファイルは、各デフォルトクラスのプロファイリングされた実装があるので動作します。私は専門を持っているそれらのプロファイルを除外@Profile({"default","IT", "<all other profiles which have NOT a specialized implementation"}
など、または@Profile("!CH")
デフォルトクラスに定義する必要 - :
は 私はせずに、このシナリオをカバーするためのより良い方法をしたいと思いますと言いました。私はここで、iこれを解決したいと思います)次に
; - DefaultMapper
に私は@Primary
としてマークされ、コンテナがすべてでそれを好きではない専門に持っているので、私が思う@Primary
は、soultionではありませんすべての注入されたクラスを決定することができます。Beanの解決があいまいである場合、実装を選択したい(コンテナ内で)プログラム的に決定したいと思います。 i.E nationality.cantidate = CHのapplication.propertiesに設定された値と比較して、@Profile、i.E @Candidate( "CH")と同様にAnnotationが適していると思います。何かのように:私はCDI SPI延長ウィッヒと同様の過去の何かでやった
public class MyExtension extends UnknowSpringType {
@Override
Object resolveAmbigousDependency(final Context ctx, final Resolution resolution) {
final List<Class> clazzes = resolution.getResolvedClasses();
for (final Class clazz : clazzes) {
if (clazz.isAnnotationPresent(Candidate.class) && clazz.getAnnotation(Candidate.class).getVaue().equals(candidateApplicationPropertyValue)) {
return clazz;
}
return getDefaultImplementation(clazzes);
}
}
エレガントであり、また、私はCDIから@Specializes
と別の方法でこれをカバーすることができますが、私は上と同じ簡単な方法を見つけることができません春(私はあまり経験がない)、BeanFactory? BeanFactoryPostProcessor?
ヘルプ?
のデモがうまくいくように見えますが、このようなものを試してみたところ、動作していなかったのでもう一度試してみます。 ' @Primary @Profile(値= {MigrationProfiles.DEFAULT}) @Target({ElementType.TYPE、ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented公共@interfaceのPrimaryProfiles { @AliasFor(annotation = Profile.class、attribute = "value") String [] value(); } ' – Tama
幸いにも、私は愚かです、私のシナリオではプライマリで私はデフォルトクラスで@Primaryを取ることを忘れていました。私をこの世界に連れてきてくれてありがとう。 – Tama
いいえ、私は助けることができてうれしい – Plog