JAVA Spring MVC Thread 解决自动注入问题
在Spring MVC中我们往往想要程序初始化的时候就能启动某一个线程来做某些工作,具体步骤如下:
1,在Spring MVC中想要启动某个class下的方法,在web.xml文件中这样配置,在启动server时默认地会执行
<servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>com.siemens.wos.wp3.dapf.startup.InitServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
2,我们将线程的start()函数写在InitServlet类中
private ServerStatusWatcherThread serverstatusmonitorThread;
public final void init() throws ServletException {
//Start ServerStatusWatcher Thread
if (serverstatusmonitorThread == null) {
serverstatusmonitorThread = new ServerStatusWatcherThread();
serverstatusmonitorThread.start();
}
}
3,继承Thread类,重写run()方法
public class ServerStatusWatcherThread extends Thread {
@Override
public void run(){
//what do you want to do please write here
}
}
4,如果想要在run()方法中调用dao层或者service层,常规的方法应该是这样
public class ServerStatusWatcherThread extends Thread {
@Resource(name="servermanageDao")
ServerManagementMapper servermanageDao;
@Autowired
ServerManagementService serverservice;
@Override
public void run(){
List<ServerManagementItem> servers =servermanageDao.getAll();
serverservice.QuerySOSServer();
//what do you want to do please write here
}
}
结果会报如下异常:Exception in thread "Thread-3" java.lang.NullPointerException
5,解决方法可以用getBean的方式来解决这个问题,异常解决
public class ServerStatusWatcherThread extends Thread {
//@Resource(name="servermanageDao")
//ServerManagementMapper servermanageDao;
//改成
ServerManagementMapper servermanageDao=(ServerManagementMapper) SpringContextUtil.getBean("servermanageDao");
//@Autowired
//ServerManagementService serverservice;
//改成:
ServerManagementService servemanagementService=(ServerManagementService) SpringContextUtil.getBean("servemanagementService");
@Override
public void run(){
List<ServerManagementItem> servers =servermanageDao.getAll();
serverservice.QuerySOSServer();
//what do you want to do please write here
}
}
方式二
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Component
@Lazy(value=false)
public class ApplicationContextHolder implements ApplicationContextAware {
private static Logger log = LoggerFactory
.getLogger(ApplicationContextHolder.class);
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext context)
throws BeansException {
synchronized (ApplicationContextHolder.class) {
if (applicationContext != null) {
throw new IllegalStateException(
"ApplicationContextHolder already holded 'applicationContext'.");
}
applicationContext = context;
log.info("holded applicationContext,displayName:"
+ applicationContext.getDisplayName());
}
}
public static ApplicationContext getApplicationContext() {
if (applicationContext == null)
throw new IllegalStateException(
"'applicationContext' property is null,ApplicationContextHolder not yet init.");
return applicationContext;
}
public static Object getBean(String beanName) {
return getApplicationContext().getBean(beanName);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Object getBean(Class clazz) {
return getApplicationContext().getBean(clazz);
}
public static void cleanHolder() {
applicationContext = null;
}
}
使用方式与上一种类似:
在Thread的对象中
private CenterService centerServiceTest=(CenterService)ApplicationContextHolder.getBean(CenterService.class);