2

次の (ウィケット) コードを検討してください。

@SpringBean(required=false)
private StatusCheckService service;

私のユースケースでは、コンテキストに StatusCheckService タイプの Bean はありません。これは問題ではありません。オプションとしてマークされているため、(ウィケット) ページは正常に初期化されます。

でも:

@SpringBean(name = "statusCheckService", required=false)
private StatusCheckService service;

これは失敗します:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'statusCheckService' is defined
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:529)
     at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1095)
     at org.springframework.beans.factory.support.AbstractBeanFactory.isSingleton(AbstractBeanFactory.java:400)
     at org.springframework.context.support.AbstractApplicationContext.isSingleton(AbstractApplicationContext.java:1113)
     at org.apache.wicket.spring.SpringBeanLocator.isSingletonBean(SpringBeanLocator.java:100)
     at org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory.getFieldValue(AnnotProxyFieldValueFactory.java:140)

違いはないと思います。OK、そのような名前の Bean はありませんが、オプションとしてマークしたので、なぜ例外なのですか? これを回避する方法はありますか?

4

1 に答える 1

1

Eclipse で使用法検索を行うと、必要な値についてアノテーションが照会されるのは、AnnotProxyFieldValue の 215 行目だけであることがわかります。

if (names.isEmpty())
{
    if (annot.required())
    {
        throw new IllegalStateException("bean of type [" + clazz.getName() + "] not found");
    }
    return null;
}

ここで、@SpringBean アノテーションの「必須」フィールドは、名前リスト (関数の上位に設定) が空の場合にのみ使用されることがわかります...

これは、名前を指定しないと名前リストが空になり (クラスが見つからないため)、null が返されるため、発生している動作を説明しています。ただし、名前を指定すると、クラスが存在するかどうかを確認しようとする必要がないため、提供されたクラス名を春に送信して検索し、クラスが見つからない場合に文句を言います。

これは、デザイナーの意図によってはバグである可能性があります。個人的には、フィールドが不要であると指定した場合、関数は早期に返されるはずだと思います...同意する場合は、クイックスタートで jira チケットを入れることを検討してください。

解決策については、ユースケースと、Bean を注入する必要がないにもかかわらず名前を設定する必要がある理由についてはあまり言及していません。しかし、特定の基準に基づいて Bean を動的に注入するためにそれを行っていると仮定すると、次のようなことができます: (未テスト)

SpringBean が注入されるクラスで、以下を置き換えます。

@SpringBean(name="statusCheckService", required=false)
private StatusCheckService service;

と:

MyCustomSpringBeanInjector injectedService;

そして MyCustomSpringBeanInjector クラスは次のようなものです:

import org.apache.wicket.injection.Injector;
import org.apache.wicket.spring.injection.annot.SpringBean;

public class MyCustomSpringBeanInjector
{
    @SpringBean public StatusCheckService service;

    public MyCustomSpringBeanInjector()
    {
        Injector.get().inject(this);
    }
}

次に、SpringBean が注入されていたクラスに戻り、次のように記述します。

if(statusCheckServiceRequired)
    injectedService = new MyCustomSpringBeanInjector();

「サービス」に置き換えます。必要に応じて「injectedService.service」を使用します。

明らかに、これは私の頭の上からの簡単な修正であり、それを行うためのより良い方法があると確信していますが、アイデアはわかります! :)

頑張ってください!

于 2012-07-18T09:40:28.827 に答える