2017-09-21 35 views
0

Java Sprintには、FTPサーバーにtxtを生成する外部システムからデータをインポートするために、毎日タスクを実行するAPIがあります。 私が持っている問題は、Autowiredフィールドがautowiredされていないということです。つまり、nullです。TimerTaskで自動応答しない

私は@PostConstructを使用して、アプリケーションが起動するたびにタスクを実行しています。そのため、Timerでアクションをスケジュールできます。

試みここで1

は、私が21.05で毎日機能をスケジュールしています、だからここのコード(最初PostContruct方法)

@Override 
    @PostConstruct 
    @Transactional 
    public Response importdata(){ 
     Response response = new Response(); 
     try { 
      System.out.println("*** Setting Import ****"); 
      Calendar calendar = Calendar.getInstance(); 
      calendar.set(Calendar.HOUR_OF_DAY, 21); 
      calendar.set(Calendar.MINUTE, 5); 
      calendar.set(Calendar.SECOND, 0); 
      calendar.set(Calendar.MILLISECOND, 0); 

      Timer time = new Timer(); // Instantiate Timer Object 
      time.schedule(new ImportServiceImpl(), calendar.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      response.setCode(CodeList.EXCEPTION); 
      response.setSuccess(false); 
     } 
     return response; 
    } 

です。

ここでは、その後、だから私は

if(this.clientDao == null) 
    this.clientDao = new ClientDaoImpl(); 

を実行しようとしました ....ここImportServiceImpl

@Component 
public class ImportServiceImpl extends TimerTask implements ImportService{ 

    @Autowired 
    InvoiceDao invoiceDao; 

    @Autowired 
    ClientDao clientDao; 

    @Override 
    @Transactional 
    public void run() { 
     System.out.println("*** Running **** " + new Date()); 
     startImport(); 
    } 

    @Override 
    @Transactional 
    public void startImport() { 
     Path dir = Paths.get(ResourcesLocation.IMPORT_ROUTE); 
     Boolean success = true; 
     try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) { 
      for (Path entry : stream) { 
       if (!Files.isDirectory(entry)) { 
        BufferedReader br = new BufferedReader(
          new InputStreamReader(new FileInputStream(ResourcesLocation.IMPORT_ROUTE + entry.getFileName().toString()))); 
        System.out.println("*** Importing file **** " + ResourcesLocation.IMPORT_ROUTE + entry.getFileName().toString()); 
        try { 
         String line; 
         int i = 0; 
         while ((line = br.readLine()) != null) { 

          final String[] parts = line.split("\\|"); 
          System.out.println("Line: " + i++ + " Text: " + line); 
          System.out.println("Factura: " + parts[1]); 
          Client client = (Client) this.clientDao.get(parts[0]); 
          String invoiceNumber = this.generateInvoiceNumber(parts[1].substring(1).replace("-", "")); 
          Invoice inv = (Invoice) this.invoiceDao.getByNumber(invoiceNumber); 
          if(inv == null){ 
           inv = new Invoice(); 
           inv.setClient(client); 
           inv.setNumber(invoiceNumber); 
           inv.setDate(this.convertDate(parts[2])); 
           inv.setTotal(this.convertFloat(parts[3])); 
           inv = (Invoice) this.invoiceDao.addOrUpdate(inv); 
          } 
         } 
        } 
        catch (Exception e) { 
         e.printStackTrace(); 
         success = false; 
        } 
        finally { 
         try { 
          br.close(); 
         } catch (IOException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
         if(success){ 
          try { 
           Files.delete(entry); 
          } catch (IOException e) { 
           // TODO Auto-generated catch block 
           e.printStackTrace(); 
          } 
         } 
        } 
       } 
      } 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
    } 

問題がthis.clientDaoがautowiredしなければならないということですが、それがnullだ持っているが、 ClientDaoImplのgetメソッドで私は

@SuppressWarnings("unchecked") 
    public Object get(String name) throws Exception 
    { 
     Query q = sessionFactory.getCurrentSession() 
       .createQuery("from " + this.entity + " WHERE name = '" + name + "'"); 
     return q.uniqueResult(); 
    } 

そしてそこにsessionFacその後、私はクラスImportServiceImplをAutowiredしようとした代わりの初期化...

Attemp 2

それはautowiredていなかったとして保守党は...ヌルだったと私は解決策は、手動ですべてのクラスを初期化し維持することであるとは思いません手動とで自分のコードを変更:

@Autowired 
    ImportService importService; 

time.schedule(this.importService, calendar.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); 

しかしthis.importServiceではないので、私はエラーをそこに着くImportServ iceImpl、それはインタフェースであるImportServiceであり、インタフェースはTimerTaskを拡張できません。実装とないインタフェースをautowiredする

3試み

変更Autowiredクラス。このよう :

@Autowired 
    ImportServiceImpl importService; 

は、だから私は、次のエラーを取得する:

java.lang.IllegalArgumentException: Can not set com.app.services.ImportServiceImpl field com.app.services.InvoiceServiceImpl.importService to com.sun.proxy.$Proxy184 

私はWhy is my Spring @Autowired field null?

で答えを確認しかし、コンテキストがsettedされることはありませんよう、手動ソリューションが機能していません。また、@Configureアノテーションを試してみましたが、これもここで示唆されています。または、私はそれを使用する方法を知っていないか、動作していません。例を単純化するために

: 私は、アノテーション@PostConstructとメソッドのimportdataはを持つクラスInvoiceServiceImplを持っているので、それはアプリ起動後に呼ばれています(一部はOKです)importdataはメソッド、クラスImportServiceImplためTimerTaskををスケジュール(ここまでは順調ですね)。しかし、適切なタイミングでメソッドが実行されますが、timertaskクラスのメソッド内の@Autowiredプロパティはnullです。

答えて

1

は、私は、コードの編成方法の小さな変更を提案する必要が

を更新しました。

まず、ImportServiceが定義されています。

public interface ImportService { 
    public void startImport(); 
} 

および関連する実装。

@Service 
public class ImportServiceImpl implements ImportService { 

    @Autowired 
    private InvoiceDao invoiceDao; 

    @Autowired 
    private ClientDao clientDao; 

    @Override 
    @Transactional 
    public void startImport() { 
     // Process... 
    } 

その後、あなたはあなたのTimerTask実装を持っています。

@Component 
public class ImportTimerTask extends TimerTask { 

    @Autowired 
    private ImportService importService; 

    @Override 
    public void run() { 
     importService.startImport(); 
    } 
} 

最後に、どのクラスにも@PostConstructメソッドがあります。このような実装では

@Autowired 
private ImportTimerTask importTimerTask; 

@PostConstruct 
@Transactional 
public void importData() { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.HOUR_OF_DAY, 9); 
    calendar.set(Calendar.MINUTE, 2); 
    calendar.set(Calendar.SECOND, 0); 
    calendar.set(Calendar.MILLISECOND, 0); 
    Timer time = new Timer(); 
    time.schedule(importTimerTask, calendar.getTime(), 
      TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); 
} 

、私の簡単なテストはinvoiceDao、罰金だったとcliendDaoが正常にautowiredました。


あなたはhereを見つけることができますしようとしました。3.

以上の基準を実装するために@Configurationクラスで@EnableAspectJAutoProxy(proxyTargetClass=true)を追加してみてくださいすることができます。

+0

私は自分のWebConfigにあることを追加しましたが、それはうまくいきませんでした: 設定 @ EnableWebMvc @ EnableAspectJAutoProxy @(proxyTargetClass =真) パブリッククラスのWebConfigはWebMvcConfigurerAdapter {... は、今私は($ Proxy174エラーを取得していますが拡張番号が重要かどうかわからない) – Faabass

+0

コード修正提案の回答が更新されました。希望が役立ちます。 – lzagkaretos

+1

ああ男!あなたは私の人生を救う!それはチャンピオンのように動作します! – Faabass

関連する問題