0

私は、既存のコードに多くの手動セットアップがあり、main メソッドで実行されるクラスを一緒に配線するプロジェクトに取り組んでいます。これは、Spring が置き換えるのが得意なものの完璧な例のようです。親クラス Widget を共有するオブジェクトがいくつかあります。各ウィジェットには、依存する他のウィジェットのリストが含まれています。

例として、これをコードで書くとしたら、次のようになります。

class Widget{ void addDependency(Widget w}{..}}

class A extends Widget{...}
...
class G extends Widget{...}

A a = new A();
...
G g = new G();

a.addDependency(b);
b.addDependency(c);
b.addDependency(d);
b.addDependency(f);
c.addDependency(g);

明らかに、ウィジェットの @Autowired コレクションだけを持つことはできません。これは、すべてのウィジェットのコレクションを取得するためです。@Autowired を除外して、特定のサブタイプのインスタンスのみを取得する方法はありますか?

私が好きではないこれを行うには2つの方法があります。1 つ目は、すべての非ウィジェット Bean をワイヤリングし、コンテキストがロードされた後にウィジェット コレクションを一緒にワイヤリングすることです。これを行うもう 1 つの方法は、@Resource を使用して ApplicationContext にワイヤリングし、@PostConstructor を使用して必要なものを取得することです。 ApplicationContext から必要です。どちらもエレガントではないようですが、別の方法はありますか?

4

2 に答える 2

1

おそらく @Matt のやり方と同じように行うでしょうが、カスタムBeanPostProcessorの作成を検討するかもしれませんが、Matt の方法の方が安全だと思います。

次に、カスタム アノテーションを作成します。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Dependencies {
    Class<?>[] value();
}

各ウィジェットに注釈を付けます

@Dependencies({WidgetB.class,WidgetC.class})
public class WidgetA extends Widget {
}

次に、@Matt Bean の検索を行います ( Spring の BeanFactoryUtilsをチェックアウトする必要があります) から依存関係を引き出しbean.getClass().getAnnotation(Dependencies.class)ます。

注釈の代わりに、Bean のプロパティを実行して、deps をリストすることができます。

于 2012-08-19T15:59:25.670 に答える
0

@PostConstructで春に試したことのサンプルを含めなかったので、これが私がやろうとしていることです。

@Component
public WidgetBuilderComponent {
    @Autowired
    private ApplicationContext context;

    @Bean
    public A a() {
        return new A();
    }

    @PostConstruct
    public void populate() {
        A a = a();
        for (B b: context.getBeansOfType(B.class).values()) {
            a.addDependency(b);
        }
    }
}

他のタイプにも同様のクラスがあります。特定のタイプの複数のインスタンスが必要な場合は、複数の@Beanメソッドを作成し、@PostConstructメソッドにそれぞれを適切に設定してください。このようなクラスは、同じコンテキストに複数回配置することはできないことに注意してください。

これはいつでもFactoryBean+InitializingBeanに置き換えることができます。これは、もう少し再利用可能ですが、同じことを実現します。

もう1つの方法は、@ Componentを配線に使用することです。これにより、ウィジェットが自分で構築し、配線について心配する必要がなくなります。

@Component
public WidgetPopulatorComponent {
    @Autowired
    private ApplicationContext context;

    @PostConstruct
    public void populate() {
        for (A a: context.getBeansOfType(A.class).values()) {
            for (B b: context.getBeansOfType(B.class).values()) {
                a.addDependency(b);
            }
        }
    }
}
于 2012-08-18T03:25:21.677 に答える