寫了一個告警推送的websocket,因爲類中用到了其它bean因此天然的用@Autowired註解將bean注入:
@ServerEndpoint(value = "/alarm/{id}", configurator = SpringConfigurator.class)
public class AlarmEndpoint {
@Autowired
private AlarmSimulator alarmSimulator;
@OnOpen
public void onOpen(Session session, @PathParam(value = "id") Long id) {
.....
}
}
調試過程當中發現onOpen函數中的alarmSimulator 的值是null,說明注入失敗了。
隨後想到用構造函數的方法試試:
@Autowired
public AlarmEndpoint(AlarmSimulator alarmSimulator){
this.alarmSimulator = alarmSimulator;
}
結果啓動時報錯,看了看錯誤信息,應該是初始化endpoint時要調用無參數的構造函數。
隨後在網上查到不能用自動注入的方式,用代碼獲取bean。
ContextLoader.getCurrentWebApplicationContext().getBean("name")
可是死活找不到alarmSimulator
又發現有人說這樣能夠拿到註解注入的bean
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
public static Object getBean(String name){
applicationContext.getBeanDefinitionNames();
return applicationContext.getBean(name);
}
}
而後把此類注入的spring的配置文件中,可是狀況跟上面同樣,找不到bean。調試了一下發現,貌似這種方法找到的bean都是在applicationContext.xml中定義的,
因此想到在springMVC.xml中注入上面定義的類,順利拿到alarmSimulator。看來getCurrentWebApplication.getBean方法拿不到也是這個問題。
獲得結論,spring對applicationContext.xml中的bean和spring mvc中的bean是分開管理的,應該有兩個applicationContext。