2016-08-21 70 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在計劃任務中工作的示例代碼? –

相關問題