SpringMVC自动注入空指针

最近做一个定时任务的需求时出现了springmvc自动注入报空指针的问题,在网上各种查找资料终于解决了。下面分享下这两天的经验。


package com.csot.ecp.web.listener;

import javax.inject.Inject;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.csot.ecp.web.timer.JudgeEmailSendLogTimer;

public class JudgeEmailAutoSendListener implements ServletContextListener {
  
  @Inject
  private JudgeEmailSendLogTimer rt;
//一开始是采用new JudgeEmailSendLogTimer()的方式去调用其start的方法 

  
  @Override
  public void contextInitialized(ServletContextEvent event) {
    String status ="Judge Email Send Listener start";
    event.getServletContext().log(status);
    System.out.println(status);       
    rt.start();
  }

  @Override
  public void contextDestroyed(ServletContextEvent event) {
    
    String status ="Judge Email Send Listener stop";
    event.getServletContext().log(status);
    System.out.println(status);
    
    if(rt !=null){
      rt.stop();
    }

  }

package com.csot.ecp.web.timer;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;

import javax.inject.Inject;
import javax.inject.Named;

@Named
public class JudgeEmailSendLogTimer {
    
  @Inject
  private JudgeEmailSendLogTask task;
  
  private final Timer timer =new Timer();  
    
  public void start(){
    final String time = "08:30:00";
    long datespan =24*60*60*1000;
    Date startTime;
    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd " + time);
    try {      
      startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(sdf.format(new Date()));
      timer.schedule(task, startTime, datespan);
//task这里开始也是用new JudgeEmailSendLogTask ()的方式去执行timer定时任务,结果发现其run()方法里面@Inject注入的变量
为空

    } catch (Exception e) {      
      e.printStackTrace();
    }    
  }
  
  public void stop(){
    timer.cancel();
  }
}

然后又是各种找“度娘”,最后发现是new出来的对象并没有交给spring去管理,那你这个类又去注入其它的变量肯定是会报空指针的。

就比如:

public class A{
  new B().update();
}

public class B{
 @Resource
 private C c;

 public update(){
   c.update();//这里会报空指针
 }

}

你c交给spring管理了,那么b也要交给spring管理才行,这样c才能注入到b中,a中new才可以用,A 、 B 、 C 都要给Spring管理, 并且不能new才可以。 


这时候候debug发现即使改为全部spring注入也会报空指针。

。。。

又是折腾了半天,最后实在不行只能找高手来帮忙了。

“听君一席话胜读十年书啊!” 突然恍然大悟。

因为spring本身也是一个listener,并不鞥保证spring比web.xml的listener更早加载,这就导致了系统在启动后有可能spring的bean还未初始化。

找到原因问题就好解决了^^

一:在不改动源程序的情况下在listener里面手动再加载一遍spring配置文件,但这对系统性能会有一定的影响。

二:采用Quartz或者spring-Task来实现

最后采用了Spring-Task的方式来实现,虽然没有Quartz那么功能强大,但Spring-Task配置简单,而且我原有的代码也不用做太多改动!其实一开始如果不用Timer直接用Quartz或者Spring-Task就没有多问题了!^_^

下面是最终实现代码:


@Component("judgeEmailSendLogTask")
public class JudgeEmailSendLogTask {

  @Inject
  private JudgeAccessFacade judgeAccessFacade;
  
  @Inject
  private ArrangeAccessFacade arrangeAccessFacade;
  
  @Inject
  private EmployeeAccessFacade employeeAccessFacade;
  
  @Inject
  private SysMailAccessFacade sysMailAccessFacade;
  
  @Inject
  private JudgeConfigFacade judgeConfigFacade;
  
  @Inject
  private SubActivityAccessFacade subActivityAccessFacade;
  
  //系统地址
  @Value("${SystemUrl}")
  private String systemUrl;
  
  //评委不可排时间设置页面菜单ID
  @Value("${JudgeNoArrangeTimeSetId}")
  private String judgeNoArrangeTimeSetId;
  
  private static final Logger LOGGER = LoggerFactory.getLogger(JudgeEmailSendLogTask.class);
 
  @Scheduled(cron = "0 30 8 * * ?")
  public void run() {
    String subject = "ECP认证安排不可排时间设置";    
    long nh = 1000 * 60 * 60;
    try {
      List<String> sendEmailjudgeCodeList = judgeAccessFacade.queryAllJudgeEmailSendLog();
      //去掉重复元素
      HashSet<String> set = new HashSet<String>(sendEmailjudgeCodeList);
      sendEmailjudgeCodeList.clear();
      sendEmailjudgeCodeList.addAll(set);
      
      SubActivityDTO subActivityDTO = new SubActivityDTO();
      List<SubActivityDTO> queryList = subActivityAccessFacade.queryAllSubActivity(subActivityDTO);
      
      JudgeArrangeDTO judgeArrangeDTO = new JudgeArrangeDTO();    
      List<JudgeArrangeDTO> judgeList = arrangeAccessFacade.queryJudgeArranges(judgeArrangeDTO);
      List<String> AlljudgeCodeList = new ArrayList<String>();
      for(JudgeArrangeDTO judgeDTO :judgeList ){
        AlljudgeCodeList.add(judgeDTO.getJudgeCode());
      }
      HashSet<String> hset = new HashSet<String>(AlljudgeCodeList);
      AlljudgeCodeList.clear();
      AlljudgeCodeList.addAll(hset);
      
      if(AlljudgeCodeList.size()>sendEmailjudgeCodeList.size()){
        AlljudgeCodeList.removeAll(sendEmailjudgeCodeList);
      }
      for(String alljudgeCodeList:AlljudgeCodeList){
        EmployeeDTO employeeDTO = employeeAccessFacade.getEmployeeById(alljudgeCodeList);
        if (employeeDTO == null) {
          continue;
        }
        String email = employeeDTO.getEmail();
        if (StringUtils.isEmpty(email)) {
          continue;
        } else {
          for(SubActivityDTO subActivityDTOList : queryList){
            Date applystartdate = subActivityDTOList.getApplyStartDate();
            Date currentdate =new Date();
            String totalActivityId = subActivityDTOList.getTotalActivityId();
            long diff = currentdate.getTime() - applystartdate.getTime();
            long hour = diff / nh;
            if(hour>8.5 && hour<24){
              // 发送邮件
              //String projectUrl=request.getScheme()+"://"+ request.getServerName()+":"+request.getServerPort()+request.getContextPath();
              String mailContent = "Dear " + employeeDTO.getName()
                  + ":<br><br>  请点击以下链接设置不可排时间:"
                  + "<br><br>"+systemUrl+"/?extRoute="+judgeNoArrangeTimeSetId+"a  ";
              boolean result = sysMailAccessFacade.sendMailCommon(subject, mailContent, email, "", "");
              if(result == true){
                //邮件发送成功将该评委记录到表中
                CreateJudgeEmailSendLogCommand command = new CreateJudgeEmailSendLogCommand();
                command.setJudgeCode(alljudgeCodeList);
                command.setJudgeName(employeeDTO.getName());
                command.setTotalActivityId(totalActivityId);
                judgeConfigFacade.createJudgeEmailSendLog(command);
               }
            }
          }       
       }
  }
    } catch (Exception e) {           
      LOGGER.error("定时发送邮件失败", e);
    } 
 }
}

有理解错误的地方欢迎指正哈!---


猜你喜欢

转载自blog.csdn.net/rixingbeioul46364/article/details/76190184
今日推荐