Spring@Autowired注释不';不能在Java TimerTask中工作

Spring@Autowired注释不';不能在Java TimerTask中工作,java,spring,autowired,timertask,Java,Spring,Autowired,Timertask,如何更改我的代码使其工作 public class GetDataFromTheWarehouse implements ServletContextListener { @Autowired ScheduledTask scheduledTask; private ScheduledExecutorService scheduler = null; public GetDataFromTheWarehouse() { } public v

如何更改我的代码使其工作

public class GetDataFromTheWarehouse implements ServletContextListener {

    @Autowired
    ScheduledTask scheduledTask;

    private ScheduledExecutorService scheduler = null;

    public GetDataFromTheWarehouse() {
    }

    public void contextDestroyed(ServletContextEvent arg0) {
        try {
            System.out.println("Scheduler Shutting down successfully " + new Date());
            scheduler.shutdown();
        } catch (Exception ex) {
        }
    }

    public void contextInitialized(ServletContextEvent arg0) {
        if ((scheduler == null) || (!scheduler.isTerminated())) {
            scheduler = Executors.newSingleThreadScheduledExecutor();
            scheduler.scheduleAtFixedRate(scheduledTask, 0, 60*60, TimeUnit.SECONDS);
        }
    }
}
下面是ScheduledTask类,其中productService为空,因此每次调用productService.save()时都会失败:

@Component
public class ScheduledTask extends TimerTask {
    @Autowired
    ProductService productService;

    public void run() {
        try {
            parse();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void parse() throws IOException {
            ...
            productService.save(product);
            ...
        }
    }
}
My applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <!-- Enable autowire -->
    <context:component-scan base-package="com" />
    <context:annotation-config />

    <bean id="usersUpdateTask" class="com.demo.task.ScheduledTask">
    </bean>

    <mvc:annotation-driven /> 

    <mvc:resources mapping="/resources/**" location="/resources/" />

    <mvc:resources mapping="/views/**" location="/views/" />
    <mvc:resources mapping="/img/**" location="/img/" />
    <mvc:resources mapping="/fonts/**" location="/fonts/" />
    <mvc:resources mapping="/css/**" location="/css/" />
    <mvc:resources mapping="/js/**" location="/js/" />

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/demo" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <!-- Session Factory Declaration -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.demo.model" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.enable_lazy_load_no_trans">true</prop>
                <prop key="hibernate.default_schema">demo</prop>
                <prop key="format_sql">true</prop>
                <prop key="use_sql_comments">true</prop>
                <!-- <prop key="hibernate.hbm2ddl.auto">create</prop> -->
            </props>
        </property>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" />

     <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

</beans>

org.hibernate.dialogue.mysqldialogue
真的
真的
演示
真的
真的
我的演示结构:


当您已经在为该bean类使用@Component时,为什么要在appilcationConfig.xml中初始化ScheduledTask。将其从applicationContext.xml文件中删除

<bean id="usersUpdateTask" class="com.demo.task.ScheduledTask">
</bean>
MyService.java

package my.spring.app;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.stereotype.Component;

@Component
public class MyService {    
public String getNextMessage(){
     return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date());
   }
}
ScheduledTask.java

package my.spring.app;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTask {

@Autowired
MyService service;

@Scheduled(fixedRate = 5000)
public void process() {
    System.out.println("Processing at " + service.getNextMessage());
    }
}
样本输出

Processing at 2016-08-24T14:01:48
Processing at 2016-08-24T14:01:53
Processing at 2016-08-24T14:01:58
希望这有帮助

编辑-2:添加Spring引导示例war文件版本。使用Tomcat8进行测试。 以下两个文件已更改。其他与上述相同

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springboot-scheduler</groupId>
<artifactId>springboot-scheduler-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
     <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
</dependencies>

</project>

当您已经在为该bean类使用@Component时,为什么要在appilcationConfig.xml中初始化ScheduledTask。将其从applicationContext.xml文件中删除

<bean id="usersUpdateTask" class="com.demo.task.ScheduledTask">
</bean>
MyService.java

package my.spring.app;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.stereotype.Component;

@Component
public class MyService {    
public String getNextMessage(){
     return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date());
   }
}
ScheduledTask.java

package my.spring.app;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTask {

@Autowired
MyService service;

@Scheduled(fixedRate = 5000)
public void process() {
    System.out.println("Processing at " + service.getNextMessage());
    }
}
样本输出

Processing at 2016-08-24T14:01:48
Processing at 2016-08-24T14:01:53
Processing at 2016-08-24T14:01:58
希望这有帮助

编辑-2:添加Spring引导示例war文件版本。使用Tomcat8进行测试。 以下两个文件已更改。其他与上述相同

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springboot-scheduler</groupId>
<artifactId>springboot-scheduler-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
     <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
</dependencies>

</project>

谢谢你的建议:)我最初的问题解释了我的情况,但被大卫·马科贡编辑(删除)。以下是删除的内容:我发现有类似的问题,我遵循了这些解决方案,但没有起作用(可能我误解了它们):Spring@autowired annotation with java TimerTask不起作用Spring autowired annotation with java TimerTask如何更改代码使其起作用?如果可能,请显示工作代码。我是一个Java新手,我按照一些教程制作了这个演示,可能有很多代码或结构看起来很奇怪。你想使用TimerTask的具体原因是什么?您可以在ScheduledTask类的parse()方法中使用Spring“@Scheduled”注释。请在“谢谢”处查看春季指南。但原始问题仍然存在:无法在计划任务中使用自动连线ProductService ProductService(ProductService为null)。您是否有任何Autowired在计划任务中工作的示例代码?能否粘贴更新后的applicationContext.xml和ScheduledTask文件?我认为“@Autowired”无法工作的原因正如@M.Deinum所述:“您正在自动连接一个ServletContextListener,它通常不是spring管理的,因此不会收到任何自动连接的内容。”感谢您的建议:)我最初的问题解释了我的情况,但已被编辑(删除)David Makogon。以下是删除的内容:我发现有类似的问题,我遵循了这些解决方案,但没有奏效(可能是我误解了它们):Spring@autowired annotation with java TimerTask不起作用Spring autowired annotation with java TimerTask如何更改我的代码以使其工作?如果可能,请显示已工作的代码。我是java新手,我按照一些教程制作了此演示,可能会有很多代码或结构看起来很奇怪。您有什么具体的原因ant是否要使用TimerTask?您可以在ScheduledTask类的parse()方法中使用Spring“@Scheduled”注释。请参阅位于的Spring指南。但原始问题仍然存在:无法在计划任务中使用Autowired ProductService ProductService(ProductService为null)。您是否有任何Autowired在计划任务中工作的示例代码?能否粘贴更新后的applicationContext.xml和ScheduledTask文件?我认为“@Autowired”不工作的原因是@M.Deinum提到的:您正在自动连接一个ServletContextListener,它通常不是spring管理的,因此不会接收任何自动连接的内容。“自动连线的
@Autowired
字段不能为
null
。如果发生这种情况,应用程序的启动将失败,出现
BeanCreationException
。现在,如果它是
null
,那是因为您自己创建实例,而不是spring。您正在自动连接一个
ServletContextListener
,它通常不是spring管理的,因此不会收到任何自动连接的内容。谢谢。因此,在Tomcat启动网站后,如果我不使用
ServletContextListener
,并且想执行一些计划任务,其中将应用
@Autowired
productService
,我可以尝试什么解决方案?一个
@Autowired
字段不能为
null
。如果发生这种情况,应用程序的启动将失败,出现
BeanCreationException
。现在,如果它是
null
,那是因为您自己创建实例,而不是spring。您正在自动连接一个
ServletContextListener
,它通常不是spring管理的,因此不会收到任何自动连接的内容。谢谢。因此,在Tomcat启动网站后,如果我不使用
ServletContextListener
并想执行一些计划任务,其中将应用
@Autowired
productService
,我可以尝试哪些解决方案?