SpringMVC自动注入空指针
来源:互联网 发布:网络什么客 编辑:程序博客网 时间:2024/06/11 01:04
最近做一个定时任务的需求时出现了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;@Namedpublic 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); } }}
有理解错误的地方欢迎指正哈!---
阅读全文
0 0
- SpringMVC自动注入空指针
- JdbcTemplate自动注入的时候出现空指针异常
- @Autowired注入空指针
- SSH2注入SessionFactory 空指针
- Springmvc bean依赖注入为空
- JSF+Spring注入空指针异常
- Spring注入SessionFactory的空指针异常
- 注入为什么会空指针异常
- Spring注入SessionFactory的空指针异常
- spring 项目多线程 依赖注入 空指针
- 【Spring】Service 注入失败,空指针
- filter注入service报空指针
- 依赖注入导致的空指针异常
- Spring注入SessionFactory的空指针异常
- 关于@Autowired自动注入属性为空
- springmvc 自动注入静态service 解决方案
- SpringMvc中自动注入失败原因
- SpringMVC之自动注入Request对象
- 同样是App渠道统计,为什么差别那么大
- android之seekBar
- 蛇形填数*
- 数据标准化/归一化normalization
- javaweb项目搭建ehcache缓存系统
- SpringMVC自动注入空指针
- A. Alice and Bob----最大公约数
- win10部分软件窗口显示不完整解决办法
- h5自定义滚动条的样式range
- 前端解决跨域问题的八种方案
- 05-非关系型数据库产品介绍
- photoswipe之图片浏览应用
- 重载
- fragment中显示toast