1
@Service
public class LogProcessorServiceImpl {
    @Autowired
    private static ApplicationConfigurationService applicationConfigurationService;

    public static void processPageRequestsLogs() {
        if(applicationConfigurationService==null) {
            System.out.println("autowire failed");
        }

私は ApplicationConfigurationService サービスをこのようにどこでも自動配線しており、正常に動作します。このクラスのパッケージはスキャンされているため、問題はありません。この特定のメソッドが呼び出される方法に関連している可能性があります。他のすべてのサーブレットの後にロードされるサーブレットがあり、上記のメソッドを 60 秒の遅延で実行するタイマーを起動します。すべての自動配線が完了する必要があると思います。

public class ProcessSchedulerServlet implements javax.servlet.Servlet {
    Timer timer=new Timer();

     @Override
     public void init(ServletConfig arg0) throws ServletException {
         timer.scheduleAtFixedRate(new TimerTask() {
             public void run() {
                 LogProcessorServiceImpl.processPageRequestsLogs();
             }
         }, 60*1000, 120*1000);
     }

ApplicationConfigurationService を使用するとすぐに、次のことが起こります。

autowire failed
Exception in thread "Timer-1" java.lang.NullPointerException
at com.siteadmin.services.impl.LogProcessorServiceImpl.processPageRequestsLogs(LogProcessorServiceImpl.java:39)
at com.siteadmin.servlets.ProcessSchedulerServlet$1.run(ProcessSchedulerServlet.java:20)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)

=== 2012-11-18 ========================================= ==================

参照: Spring オートワイヤリングの方法

4

1 に答える 1

3

Spring で静的フィールドを自動配線することはできません。これについては、こちらで説明しています

別の方法として、ルート Web アプリケーション コンテキストLogProcessorServiceに存在する場合は、Spring WebApplicationContextUtilsユーティリティ クラスを使用して自動配線できます。

public class ProcessSchedulerServlet implements javax.servlet.Servlet {
     Timer timer=new Timer();

     @Autowired
     LogProcessorService logProcessorService;

     @Override
     public void init(ServletConfig arg0) throws ServletException {
         WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext())
            .getAutowireCapableBeanFactory().autowireBean(this);

         final LogProcessorService svc = this.logProcessorService;
         timer.scheduleAtFixedRate(new TimerTask() {
         public void run() {
             svc.processPageRequestsLogs();
         }
         }, 60*1000, 120*1000);

一般に、Spring シングルトンを使用するだけで十分な場合は、Java シングルトンの使用を避ける必要があります。

また、アノテーションで宣言LogProcessorServiceImplした場合@Service、Spring シングルトンであることを意味するため、静的フィールドを使用しないでください。

PS この回答は自動配線に関するものです。TimerTask のアイデアが正しいと想定しています。実際のアプリでは、Spring Scheduling APIの使用を検討してください。

于 2012-11-18T05:39:42.033 に答える