4

Bean をヘルパー クラスに注入する際に問題があります。基本的には次のように動作します: ページ コンストラクターでオブジェクトを作成し、何らかの作業を行い、データを返し、それらをページに表示します。このヘルパー オブジェクトでは、@Autowiredアノテーションを介してサービスを注入する必要があります。ただし、使用すると常にヌルポインター例外が発生します。私も試し@SpringBeanましたが、役に立ちませんでした。一方、このサービスを でページに直接挿入すると@SpringBean、アクセス可能になり、正常に動作します。どこに問題があるか知っていますか?

これはページです:

public class Page extends BasePage {
    public Page() {
        HelperObject object = new HelperObject(new Application("APP_NAME"));
        String result = object.getData();

        add(new Label("label", result));
    }
}

ヘルパー オブジェクト:

public class HelperObject {
    private Application app;

    @Autowired
    private Service service;

    public HelperObject(Application app) {
        this.app = app;
    }

    public String getData() {
        // use service, manipulate data, return a string
    }
}
4

3 に答える 3

5

コンストラクターで@SpringBean呼び出すことにより、Spring 以外の Wicket で新しく作成されたオブジェクトに依存関係を注入できます。InjectorHolder.getInjector().inject(this);

例えば:

class MyPojo {
    @SpringBean
    MyDumbDAO dao;
    MyPojo() {
        InjectorHolder.getInjector().inject(this);
    }
    void justDoIt() {
        dao.duh(); // dao is there!
    }
}

Wicket 管理のリクエスト内で呼び出された場合にのみ機能することに注意してください。そうでない場合 (つまり、Quartz ジョブ、または Wicket の前に実行されたフィルターの場合)、Applicationインスタンスは利用できず、インジェクターは依存関係を取得する方法を知りません。

別の解決策は、Spring の を使用すること@Configurableです。AspectJ を使用して、注釈付きオブジェクトの作成をインターセプトし、その依存関係を注入します。それらを直接インスタンス化する場合でもnew(または Hibernate などの他のフレームワークが内部で作成する場合でも)。しかし、これには実行時またはビルド時 (私にとってはよりうまく機能します) のバイトコード操作が必要です。

于 2011-03-24T12:56:51.520 に答える
3

ベスト プラクティスは、ファクトリ Bean を介してオブジェクトを作成することです (これには、Spring によって注入されたプロパティがあり、そのファクトリが生成するオブジェクトにそれらのプロパティを注入します - 純粋な IoC)。

SpringContext をあらゆる場所で使用することは本当に避けるべきです(または、他の同様のソリューション)。理由の部分的なリストを次に示します。

  1. あなたのコードは Spring と結合しすぎています (凝集度が低い)。
  2. 配管コードとビジネス ロジックを混在させます。
  3. あなたのコードは読みにくいです。
  4. 保守性が低くなります (たとえば、サービス Bean の名前を変更するとコードが変更されます。これは SRP と OCP に違反します)。
  5. テストしにくい (たとえば、テストするには Spring フレームワークが必要)。
于 2013-07-21T20:13:02.647 に答える
3

@SpringBeanWicket の から継承するクラスにのみ依存関係を注入しますComponent@AutowiredSpring 自体によって作成されたクラスにのみ依存関係を注入します。つまり、 で作成したオブジェクトに依存関係を自動的に注入することはできませんnew

(編集:@SpringBeanコンストラクターに注入することにより、クラスに注入を 追加することもできますInjectorHolder.getInjector().inject(this);:)

これに対する私の通常の回避策は、アプリケーション クラスを使用して支援することです。(私はあなたの の使い方に少し困惑していますnew Application(...)。これは実際には ではないと思いますorg.apache.wicket.Application。) 例えば:

public class MyApplication extends AuthenticatedWebApplication implements
    ApplicationContextAware {

    private ApplicationContext ctx;

    public void setApplicationContext(ApplicationContext applicationContext)
        throws BeansException {
        this.ctx = applicationContext;
    }

    public static MyApplication get() {
        return (MyApplication) WebApplication.get();
    }

    public static Object getSpringBean(String bean) {
        return get().ctx.getBean(bean);
    }

    public static <T> T getSpringBean(Class<T> bean) {
        return get().ctx.getBean(bean);
    }

    ....
}

私のSpringアプリケーションのコンテキストでは:

<!-- Set up wicket application -->
<bean id="wicketApplication" class="uk.co.humboldt.Project.MyApplication"/>

次に、ヘルパー オブジェクトがオンデマンドでサービスを検索します。

public class HelperObject {

    private Service getService() {
        return MyApplication.getSpringBean(Service.class);
    }
于 2011-03-24T12:30:46.697 に答える