我有一个BEAN用SPRING的注解,在CONTROLER里用@Autowired正常,但是我写了一个定时器,用@Autowired取就是空指针错。
spring配置文件:
<context:annotation-config />
<context:component-scan base-package="com.waps.alipay" />
<import resource="task.xml"/>   
=============================================================
package com.waps.alipay.action;
@Controller
public class HomeController {
@Autowired
private Config config;
@RequestMapping(value = "/", method = RequestMethod.GET)
   public String home(Locale locale, Model model) {
      logger.info(config.log_path);
   }
}
=================================================================
定时器代码 
package com.waps.alipay.job;
public class NoticeJob {
@Autowired
private Config config;
  public void run() {
    logger.info("run NoticeJob..."+config.log_path);
  }
}
=================================================================
定时器task.xml配置
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 
 
<beans>      
        <!-- 要调用的工作类 --> 
        <bean id="NoticeJob" class="com.waps.alipay.job.NoticeJob"></bean> 
        <!-- 定义调用对象和调用对象的方法 --> 
        <bean id="jobtask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
            <!-- 调用的类 --> 
            <property name="targetObject"> 
                <ref bean="NoticeJob"/> 
            </property> 
            <!-- 调用类中的方法 --> 
            <property name="targetMethod"> 
                <value>run</value> 
            </property> 
        </bean> 
        <!-- 定义触发时间 --> 
        <bean id="doTime" class="org.springframework.scheduling.quartz.CronTriggerBean"> 
            <property name="jobDetail"> 
                <ref bean="jobtask"/> 
            </property> 
            <!-- cron表达式 --> 
            <property name="cronExpression"> 
                <value>10 * * * * ?</value> 
            </property> 
        </bean> 
        
        
        <!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序  --> 
        <bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
            <property name="triggers"> 
                <list> 
                   <!-- <ref bean="doTime"/> -->  
                     <ref bean="doTime"/> 
                </list> 
            </property> 
        </bean> 
      
</beans>
SpringAutowired注解

解决方案 »

  1.   

    ERROR: org.quartz.core.JobRunShell - Job DEFAULT.jobtask threw an unhandled Exception: 
    org.springframework.scheduling.quartz.JobMethodInvocationFailedException: Invocation of method 'run' on target class [class com.waps.alipay.job.NoticeJob] failed; nested exception is java.lang.NullPointerException
            at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:308)
            at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:111)
            at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
            at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:525)
    Caused by: java.lang.NullPointerException
            at com.waps.alipay.job.NoticeJob.run(NoticeJob.java:36)
            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:601)
            at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
            at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:299)
            ... 3 more报错信息
      

  2.   

    使用AutoWire前,在applicationContext配置了吗
      

  3.   

    从异常上来看是config在没有被完成注入到NoticeJob 时被调用了;
    有可能是注入没有完成就定时器就开启了;
    spring 在 实例化 bean的时候,是分为2步的,
    第一步可以简单的认为new个对象出来,第二步为这个new出来的对象设置属性。就是去容器里面把这个bean需要的其他bean给注入进来。
    在第2步的时候,注入给其他的bean的bean 可能没有被完全bean化,很有可能只是完成了第一步的bean,还是个“半成品”。
    但是在整个容器初始化结束的时候,这些“半成品”bean会被变成“合格品”。这里可能是还没有轮到autowire的时候就开启了定时器;猜想可供尝试的方案有两种
    1 在配置文件中配置NoticeJob的config属性,因为NoticeJob bean定义本身在定时器前面,尝试在定时器启动前就注入完成;
    2 利用构造函数参数的注入方式,确保一初始化就有值;个人愚见,可以尝试一下
      

  4.   

    应该是定时任务执行时候还没有注入那个bean
    两种方法:
    1、你可以再启动时候不要先不要启动定时任务,lazy-init="true"
    2、可以通过构造。
      

  5.   

    通过日志看,那个bean应该是已经注入成功了的。因为我还另外写了一个controller,用同样的autowired就可以正常。
      

  6.   


    找到问题了,因为我的定时任务是在新的xml中引用,但这个XML里没有注入扫描包,我一直以为在DispatcherServlet的配置文件里扫描包就可以了。