Java 自动连线,TimerTask不工作

Java 自动连线,TimerTask不工作,java,spring,autowired,timertask,Java,Spring,Autowired,Timertask,我在JavaSprint中有一个API,它需要每天执行一个任务,从FTP服务器中生成txt的外部系统导入一些数据。 我遇到的问题是,自动连线字段没有自动连线。。。。我是说,它们是空的 每次应用程序启动时,我都会使用@PostConstruct来执行一项任务,因此我可以使用计时器来安排操作 尝试1 下面是代码(首先是后期施工方法) 所以在这里,我把这个功能安排在每天21点05分 这里有ImportServiceImpl @Component public class ImportServiceIm

我在JavaSprint中有一个API,它需要每天执行一个任务,从FTP服务器中生成txt的外部系统导入一些数据。 我遇到的问题是,自动连线字段没有自动连线。。。。我是说,它们是空的

每次应用程序启动时,我都会使用@PostConstruct来执行一项任务,因此我可以使用计时器来安排操作

尝试1

下面是代码(首先是后期施工方法)

所以在这里,我把这个功能安排在每天21点05分

这里有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();
        }
    }
但是,在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();
    }
因为sessionFactory不是自动连接的,所以它是空的。。我不认为解决方法是继续手动初始化每个类

尝试2

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

@Autowired
    ImportService importService;

但是在这里我得到了一个错误,因为this.importService不是ImportServiceImpl,而是importService,它是接口,接口不能扩展TimerTask

3次尝试

将Autowired类更改为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
我核对了答案

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

要简化示例,请执行以下操作:
我有一个类InvoiceServiceImpl,它有一个带有注释@PostConstruct的方法importdata,所以它在应用程序启动后被调用(这部分没问题)。importdata方法,为类ImportServiceImpl安排一个timertask(到目前为止还不错)。但在适当的时候,会执行该方法,但timertask类中该方法内的@Autowired属性为空。

已更新

我不得不建议对代码的组织方式进行一些小的修改

首先定义了
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...
    }
@Component
public class ImportTimerTask extends TimerTask {

    @Autowired
    private ImportService importService;

    @Override
    public void run() {
        importService.startImport();
    }
}
然后,就有了
TimerTask
实现

@Service
public class ImportServiceImpl implements ImportService {

    @Autowired
    private InvoiceDao invoiceDao;

    @Autowired
    private ClientDao clientDao;

    @Override
    @Transactional
    public void startImport() {
        // Process...
    }
@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
成功地自动连接


您可以尝试在
@Configuration
类中添加
@enableAspectProxy(proxyTargetClass=true)
,以实现尝试3


您可以找到更多参考。

我将其添加到我的WebConfig中,但它不起作用:@Configuration@EnableWebMvc@enableSpectjautoproxy(proxyTargetClass=true)公共类WebConfig扩展了WebMVCConfigureAdapter{..现在我得到$Proxy174错误(我不知道这个数字是否重要)用代码修改建议更新了答案。希望对您有所帮助。
@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));
}