代码之家  ›  专栏  ›  技术社区  ›  J.W

Spring@Autowired注释在Java TimerTask中不起作用

  •  1
  • J.W  · 技术社区  · 8 年前

    如何更改代码以使其正常工作?

    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.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);
                ...
            }
        }
    }
    

    我的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>
    

    我的演示结构:

    demo website structure

    1 回复  |  直到 7 年前
        1
  •  0
  •   abaghel    8 年前

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

    编辑: 添加Spring Boot示例。

    这是Spring Boot中@Scheduled with@Autowired的示例代码。

    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>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>1.4.0.RELEASE</version>
        </dependency>
     </dependencies>
    </project>
    

    package my.spring.app;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    @SpringBootApplication
    @EnableScheduling
    public class MySpringBootApp {
        public static void main(String[] args) {
        SpringApplication.run(new Object[] { MySpringBootApp.class }, args);
       }
    }
    

    我的服务.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());
       }
    }
    

    计划任务.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 Boot示例战争文件版本。使用Tomcat 8进行测试。

    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>
    

    package my.spring.app;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.web.support.SpringBootServletInitializer;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    @SpringBootApplication
    @EnableScheduling
    public class MySpringBootApp extends SpringBootServletInitializer {
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MySpringBootApp.class);
      }
    
    public static void main(String[] args) {
    
        SpringApplication.run(new Object[] { MySpringBootApp.class }, args);
    
        }
    }