代码之家  ›  专栏  ›  技术社区  ›  Faabass

自动连线,计时器任务不工作

  •  0
  • Faabass  · 技术社区  · 7 年前

    我在Java Sprint中有一个API,需要每天执行一个任务,从FTP服务器中生成txt的外部系统导入一些数据。

    尝试1

    @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;
        }
    

    这里有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();
            }
        }
    

    这里的问题是这个。clientDao应该是自动连接的,但它是空的。。。。 所以我试着去做

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

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

    因为sessionFactory不是自动连接的,所以它是空的。。我不认为解决方法是继续手动初始化每个类。。。

    然后,我尝试自动连接类ImportServiceImpl,而不是手动初始化,并用以下代码更改了代码:

    @Autowired
        ImportService importService;
    

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

    但我得到了一个错误,因为这个。importService不是ImportServiceImpl,它是作为接口的importService,接口不能扩展TimerTask。

    这样地:

    @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?

    但是手动解决方案不起作用,因为从未设置上下文。此外,我还尝试了@Configure注释,这也是这里建议的,或者我不喜欢;我不知道如何使用它,否则它不起作用。

    我有一个类InvoiceServiceImpl,它有一个方法importdata,带有注释@PostConstruct,所以在应用程序启动后(这部分没问题)调用它。importdata方法,为类importserviceinpl安排一个timertask(到目前为止很好)。但当时机合适时,会执行该方法,但timertask类中方法内的@Autowired属性为null。

    1 回复  |  直到 7 年前
        1
  •  1
  •   lzagkaretos    7 年前

    已更新

    首先 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 已成功自动连线。


    您可以尝试添加 @EnableAspectJAutoProxy(proxyTargetClass=true) @Configuration 类以实现尝试3。

    您可以找到更多参考资料 here .