3

Cron4Jスケジューラを初期化して起動するために使用しているカスタムServletContextListenerがあります。

public class MainListener implements ServletContextListener {
    @Value("${cron.pattern}")
    private String dealHandlerPattern;

    @Autowired
    private DealMoqHandler dealMoqHandler;
}

示されているように、Listener 内のいくつかのオブジェクトを自動配線しており、Spring でリスナーのインスタンス化を管理したいと考えています。を介してプログラムによる web.xml 構成を使用していますWebApplicationInitializerが、これまでのところ、リスナーは自動配線されていません (自動配線されていると思われるオブジェクトにアクセスしようとするたびに NullPointerExceptions が発生します)。

以下に示すように、ContextLoaderListener を追加した後、既に顧客リスナーを追加しようとしました。

public class CouponsWebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(SpringAppConfig.class);

        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));

        container.addListener(new MainListener()); //TODO Not working
    }

これらの過去の質問Spring - Injecting a dependency into a ServletContextListenerdependency inject servlet listenerを確認し、リスナーの contextInitialized メソッド内に次のコードを実装しようとしました。

    WebApplicationContextUtils
        .getRequiredWebApplicationContext(sce.getServletContext())
        .getAutowireCapableBeanFactory()
        .autowireBean(this);

ただし、次の例外が発生します。

Exception sending context initialized event to listener instance of class com.enovax.coupons.spring.CouponsMainListener: java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
at org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:90) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]

リスナーを追加する前に、Spring がすでにインスタンス化を完了していることを確認するにはどうすればよいですか?

4

2 に答える 2

2

私の間違い。元の投稿のコードが正しく、リスナーが正しい順序で追加されていることがわかりました。

問題は、カスタム リスナーに@WebListener注釈 (サーブレット 3.0) を付けたことです。これにより、Web アプリがaddListener()WebApplicationInitializer のコードを無視し、Spring の ContextLoaderListener のカスタム リスナー AHEAD をインスタンス化していました。

次のコード ブロックは、エラー コードを示しています。

@WebListener /* should not have been added */
public class CouponsMainListener implements ServletContextListener {
    @Autowired
    private Prop someProp;
}
于 2012-09-12T08:28:02.947 に答える
0

Spring Beanでは使用できませんnew。Java は Spring を気にせず、Spring にはnewオペレーターの動作を変更する方法がありません。オブジェクトを自分で作成する場合は、それらを自分で配線する必要があります。

また、初期化中に行うことにも注意する必要があります。Spring を使用する場合は、次の (単純化された) モデルを使用します。まず、Spring はすべての Bean を作成します (newそれらすべてを呼び出します)。次に、それらの配線を開始します。

したがって、autowired フィールドの使用を開始するときは特に注意する必要があります。それらをすぐに使用できるとは限りません。Spring がすべての初期化を完了していることを確認する必要があります。

場合によっては@PostProcess、循環依存関係のために Spring が Bean を作成できなかったため、メソッドで自動配線されたフィールドを使用することさえできません。

したがって、「アクセスしようとするたびに」は時期尚早だと思います。

同じ理由で、 で使用することはできませんWebApplicationContextUtils:WebApplicationInitializerまだ Spring のセットアップが完了していません。

于 2012-09-12T08:28:56.723 に答える