在SSM项目中是初始化加载Listener,实现启动程序时的一些操作
- 第一步创建listener类
package com.chenbro.datahub.listener;
import com.chenbro.datahub.model.Monitor;
import com.chenbro.datahub.model.ProdCount;
import com.chenbro.datahub.service.IMonitorService;
import com.chenbro.datahub.service.IProdCountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.annotation.PostConstruct;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.sql.Timestamp;
public class MonitorMachine implements ServletContextListener {
public static MonitorMachine monitorMachine;
private static WebApplicationContext springContext;
IProdCountService prodCountService ;
IMonitorService iMonitorService ;
@PostConstruct
public void init(){
monitorMachine = this;
}
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(servletContextEvent.getServletContext());
prodCountService = springContext.getBean(IProdCountService.class);
iMonitorService = springContext.getBean(IMonitorService.class);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
- 在web.xml文件中配置监听
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.chenbro.datahub.listener.MonitorMachine</listener-class>
</listener>
- Servlet容器初始化完成后,会调用监听器类中的contextInitialized方法。在监听器中无法通过注解的方式调用Service和Mapper。Spring框架管理和装配bean
@Autowired
IProdCountService prodCountService ;
@Autowired
IMonitorService iMonitorService ;
//程序会抛出空指针异常,无法通过注解注入
(1)Listener的生命周期是由servlet容器管理的,项目启动时的MonitorMachine是由servlet容器实例化并调用其contextInitialized方法,而servlet容器并不能识别@Autowired注解,因此导致prodCountService、iMonitorService实例注入失败。
(2)而spring容器中的bean的生命周期是由spring容器管理的。
- 在Spring容器之外如何引用Spring容器的bean实例,可以使用Spring提供的WebApplicationContextUtils工具类,该工具类的作用是获取到spring容器的引用,进而获取到需要的bean实例
WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(servletContextEvent.getServletContext());
IProdCountService prodCountService = springContext.getBean(IProdCountService.class);
注意:
1.确保Servlet容器实例化监听器调用contextInitialized前,Spring容器已经初始化完毕
2.Spring的初始化由Listener(ContextLoaderListener)完成,首先得在web.xml配置Spring容器的Listener
配置文件顺序如下:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.chenbro.datahub.listener.MonitorMachine</listener-class>
</listener>