这需求还是比较正常的,尝试了外部用@Autowired
注解引入Spring注解的Bean,然后以此为参数传入Thread
中,发现报NULLPOINTER
异常,于是放弃,而且要定义为static
,多方尝试之后,用如下的方法的得以解决问题:
首先新建SpringBean的工具类
package com.hhu.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* 创建获取SpringBean的工具类
* @author Weiguo Liu
*
*/
public class SpringBeanUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringBeanUtil.applicationContext = applicationContext;
}
public static Object getBeanByName(String beanName) {
if (applicationContext == null) {
return null;
}
return applicationContext.getBean(beanName);
}
public static <T> T getBean(Class<T> type) {
return applicationContext.getBean(type);
}
}
这里需要注意是,工具类写完了一定要在spring的配置文件中注册,如果不注册的Spring无法感知,因为网上提供了一种直接获取Bean的方法,尝试后发现不管用,可能就是这方面的原因吧,
<!--配置SpringUtil的工具类 -->
<bean id="springBeanUtil" class="com.hhu.util.SpringBeanUtil">
</bean>
后面在线程中直接调用即可
SpringBeanUtil su = new SpringBeanUtil();
public void run() {
while(true) {
StationService stationService = (StationService) su.getBeanByName("stationService");
System.out.println("当前线程:" + Thread.currentThread().getName());
Station station = stationService.getLastStation();
System.out.println("查询成功:" + station);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这里顺便记录一下,关于线程的周期性调用的问题,在网上找资料说是如下代码可以解决
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
//第一个参数是执行的线程, 第二个参数为首次执行的延时时间(初始化时延),第三个参数为定时执行的间隔时间,最后一个是计时单位
service.scheduleAtFixedRate(runnable, 5, 10, TimeUnit.SECONDS);
后来这么搞的,发现跑起来像脱缰的野马,参数完全不起作用,这与这个以后有时间在搞,附上我最后用的笨办法:
/**
* 建立连接后
*/
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("进入真正的握手类:MyWebSocketHandler,成功链接");
//这里开启一个线程去扫数据库
System.out.println("进行数据库扫描。。。。。");
if(session.isOpen()) {//如果数据库会话是开着的状态
//第一个参数是执行的线程, 第二个参数为首次执行的延时时间(初始化时延),第三个参数为定时执行的间隔时间,最后一个是计时单位
//service.scheduleAtFixedRate(runnable, 5, 10, TimeUnit.SECONDS);
//System.out.println(sdf.format(new Date()));
//service.scheduleAtFixedRate(runnable ,10, 15, TimeUnit.SECONDS);
//thread.start();
st.start();
}
}
线程类如下:
class StationThread extends Thread {
SpringBeanUtil su = new SpringBeanUtil();
public void run() {
while(true) {
StationService stationService = (StationService) su.getBeanByName("stationService");
System.out.println("当前线程:" + Thread.currentThread().getName());
Station station = stationService.getLastStation();
System.out.println("查询成功:" + station);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}