使用Spring Scheduler从DB返回行会抛出Null指针Exception

时间:2016-07-11 09:31:07

标签: spring nullpointerexception

我正在使用Spring调度来安排每小时执行一些数据库操作的任务。每次我尝试调用触发数据库特定操作的函数时,都会抛出NullPointerException

配置文件:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages="com.bt.rtddashboard")
/*@EnableJpaRepositories(basePackages = {
        "com.bt.rtddashboard"
})*/
@EnableScheduling
@PropertySource("classpath:jdbc.properties")
public class RTDDashboardConfiguration extends WebMvcConfigurerAdapter {


    @Resource
    private Environment env;

    @Bean(name = "dataSource", destroyMethod="close")
    public DataSource getDataSource() {
        //DB code
    }

    private Properties getHibernateProperties() {
            //Hibernate code
    }

    @Bean(name = "sessionFactory")
    @Scope("singleton")
    public LocalSessionFactoryBean getSessionFactory() {

    }

    @Autowired
    @Bean(name = "transactionManager")
    public HibernateTransactionManager getHibernateTransactionManager(SessionFactory factory) {
    ;
    }

    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("/").setCachePeriod(31556926);

    }

    @Scheduled(fixedRate=1000)
    public void work() {
        // task execution logic
        System.out.println("Scheduled Task");
        DashboardController controller=new DashboardController();
        controller.performTask();
    }

}

信息中心控制器:

@RestController
public class DashboardController {

    @Autowired
    private InlineService service;

    @RequestMapping(value="/rtd/getAllServers", method=RequestMethod.GET)
    public ResponseEntity<List<ServerMonitor>> getAllServers(){
        List<ServerMonitor> ilsList=new ArrayList<ServerMonitor>();
        ResponseEntity<List<ServerMonitor>> response=null;

        try{
            ilsList=service.getAllServers();
            response=new ResponseEntity<List<ServerMonitor>>(ilsList,HttpStatus.OK);
            System.out.println("Scheduled Time");

        }catch(Exception e){

        }
        return response;
    }

public  void  performTask(){
        System.out.println("Scheduled Task Starts in Contrroller");
        List<IlsStats> ilsStats =new ArrayList<IlsStats>();
        List<IlsStatsHistory> ilsStatsHisList=new ArrayList<IlsStatsHistory>();
        try{
            //get All the ILS Stats
            ilsStats=service.getAllInlineStats();
            System.out.println("No of rows to Copy : " + ilsStats.size());
            ilsStatsHisList=formILSHistoryList(ilsStats);

            int flag=service.insertInIlsStatsHistory(ilsStatsHisList);

        //List<ServerMonitor> ilsList=service.getAllServers();

        }catch(Exception e){
            e.printStackTrace();
        }
    }

此处,ilsStats=service.getAllInlineStats();会抛出NullPointerException

即使在其上创建的其余web服务工作正常。

堆栈追踪:

Scheduled Task
Scheduled Task Starts in Contrroller
java.lang.NullPointerException
    at com.bt.rtddashboard.controller.DashboardController.performTask(DashboardController.java:226)
    at com.bt.rtddashboard.configuration.RTDDashboardConfiguration.work(RTDDashboardConfiguration.java:137)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

现在每1秒就会出现相同的堆栈跟踪。

1 个答案:

答案 0 :(得分:0)

在配置类中创建@Scheduled方法是一个非常糟糕的主意(imho)。接下来我还认为让一个调度器调用一个控制器方法(一个绑定到web相关组件的方法!)通常是一个坏主意/设计。

但问题是您new DashboardController()。这显然会创建一个超出spring范围的bean,永远不会被依赖注入。而是将其注入到类中并使用该实例。

@Autowired
private DashboardController controller;

@Scheduled(fixedRate=1000)
public void work() {
    controller.performTask();
}

或者更好的方法就是一起删除该方法,只需将@Scheduled(fixedRate=1000)放在performTask方法上。