2016-08-21 169 views
0

如何更改我的代码以使其工作?Spring @ Autowired注释在Java中不起作用TimerTask

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

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

+0

一个'@ Autowired'字段不能为'null'。如果发生这种情况,应用程序的启动将失败并出现'BeanCreationException'。现在,如果它是'空',那是因为你自己创建实例而不是春天。你正在自动装配一个'ServletContextListener',它通常不是由spring管理的,因此不会收到任何自动装配的东西。 –

+0

谢谢。因此,在Tomcat启动网站之后,如果我不使用'ServletContextListener'并且想要执行一些计划任务,其中将应用'@ Autowired'' productService',我可以尝试哪些解决方案? –

回答

0

为什么你有ScheduledTask在appilcationConfig.xml当你已经在使用@Component为bean类初始化。从你的applicationContext.xml文件中删除它。

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

编辑:添加Spring引导样品。

以下是Spring Boot中@Scheduled与@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> 

MySpringBootApp.java

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

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 

希望这会有所帮助。

EDIT-2:添加Spring Boot Sample war文件版本。测试了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> 

MySpringBootApp.java

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

    } 
} 
+0

感谢您的建议:)我的原始问题解释了我的情况,但是由David Makogon编辑(删除)。这里是删除的内容:我发现有类似的问题,我遵循这些解决方案,但没有工作(也许我误解了它们): 用Java TimerTask进行Spring @autowired注释不起作用 用java timertask进行Spring自动注释注释 如何更改我的代码以使其工作?如果可能,请显示工作代码。 我是一个Java新手,我跟着一些教程来做这个演示,可能有很多代码或结构看起来很奇怪。 –

+0

你为什么要使用TimerTask的具体原因?您可以在ScheduledTask类的parse()方法中使用Spring“@Scheduled”注释。请参阅https://spring.io/guides/gs/scheduling-tasks/ – abaghel

+0

上的弹簧指南。谢谢。 但原始问题仍然存在:无法在计划任务中使用Autowired ProductService productService(productService为null)。 您是否有任何Autowired在计划任务中工作的示例代码? –