IOC容器的获取主要思想是通过配置监听器,在项目启动时,查找类路径下的applicationContext.xml文件,创建容器。或者如果项目使用全注解,则使用配置类创建容器。
项目中的容器包含关系 :
ServletContext(Tomcat创建) >
Root WebApplicationContext(IOC Web根容器)>
Servlet WebApplicationContext(SpringMVC 子容器)
如下所示在注册contextLoaderListener时会创建RootAppContext:
【1】自定义监听器获取IOC容器
实现ServletContextListener
如下是获取ClassPathXmlApplicationContext容器,这需要有applicationContext.xml文件。
public class SpringServletContextListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("容器销毁********");
}
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
//获取配置文件名称
String configLocation = servletContext.getInitParameter("configLocation");
//创建IOC容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(configLocation);
//放入servletContext中
servletContext.setAttribute("applicationContext", applicationContext);
if (applicationContext != null) {
System.out.println("IOC 容器初始化成功");
}
}
}
web.xml
<context-param>
<param-name>configLocation</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
<!-- ******启动IOC容器的ServletContextListener****** -->
<listener>
<display-name>SpringServletContextListener</display-name>
<listener-class>
com.web.listener.SpringServletContextListener
</listener-class>
</listener>
【2】Spring自带监听器进行IOC容器初始化
Spring提供了org.springframework.web.context.ContextLoaderListener
在项目启动时,自动初始化容器。同样,需要在web.xml里面配置applicationContext.xml路径;
<!-- ****Spring IOC 容器初始化**** -->
<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>
【3】获取IOC容器的两种方式
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
/*第一种取得applicationContext的方式,根据属性名获取*/
ApplicationContext applicationContext = (ApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
/*查看源码
ContextLoader.class的public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
}可知,在创建applicationContext时,将其根据属性名放入了servletContext中
*/
/*第二种取得applicationContext的方式,使用Spring提供的工具类,传入应用上下文对象,就可以获取IOC容器*/
applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
/*如果在jsp页面获取,则传入application隐式对象*/
}
【3】IOC工具类
package com.corn.core.spring;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.FrameworkServlet;
import com.corn.core.utils.ToolUtils;
public class SpringIocUtil {
private final static Logger log = LoggerFactory.getLogger(SpringIocUtil.class);
public final static String fail_info = "get %s fail,ServletContext not loading.";
public final static String springConfigFilePath = "applicationContext.xml";
public final static String success_info = "get %s success:";
public static synchronized <T> T getBean(Class<T> beanName) {
return getInstence(beanName, getContext());
}
public static synchronized <T> T getBean(Class<T> beanName,ApplicationContext context) {
return getInstence(beanName, context);
}
public static synchronized <T> T getBean(Class<T> beanName,ServletContext servletcontext) {
return getInstence(beanName, WebApplicationContextUtils.getRequiredWebApplicationContext(servletcontext));
}
public static synchronized Object getBean(String beanName) {
return getInstence(beanName, getContext());
}
public static synchronized Object getBean(String beanName,ApplicationContext context) {
return getInstence(beanName, context);
}
public static synchronized Object getBean(String beanName,ServletContext servletcontext) {
return getInstence(beanName, WebApplicationContextUtils.getRequiredWebApplicationContext(servletcontext));
}
private static <T> T getInstence(Class<T> beanName,ApplicationContext context) {
try {
if (context == null) {
log.error(String.format(fail_info, beanName));
return null;
}
T t = context.getBean(beanName);
if (t != null) {
log.debug(String.format(success_info, beanName) + t);
return t;
}
} catch (Exception e) {
log.error(SpringIocUtil.class.getName()+" T getInstence(beanName,context) ",e);
}
return null;
}
private static Object getInstence(String beanName,ApplicationContext context) {
try {
if (context == null) {
log.error(String.format(fail_info, beanName));
return null;
}
Object t = context.getBean(beanName);
if (t != null) {
log.debug(String.format(success_info, beanName) + t);
return t;
}
} catch (Exception e) {
log.error(SpringIocUtil.class.getName()+" Object getInstence(beanName,context)",e);
}
return null;
}
public static ApplicationContext getContext() {
ApplicationContext context = null;
try{
Enumeration<String> ns= SpringIocContextListener.getServletcontext().getAttributeNames();
while(ns.hasMoreElements()){
String name=ns.nextElement();
log.debug(name+" IS SERVLET_CONTEXT_PREFIX:",name.matches(FrameworkServlet.SERVLET_CONTEXT_PREFIX+"*"));
}
context = WebApplicationContextUtils.getWebApplicationContext(SpringIocContextListener.getServletcontext());
}catch(Exception e){
log.warn("Spring IOC getWebApplicationContext(sc) type fail.");
}
String name=null;
if (context == null) {
try{
name=FrameworkServlet.SERVLET_CONTEXT_PREFIX+"Spring-MVC";
context=WebApplicationContextUtils.getWebApplicationContext(SpringIocContextListener.getServletcontext(), name);
}catch(Exception e){
log.warn("Spring IOC getWebApplicationContext(sc,\""+name+"\") type fail[default].");
}
}
if (context == null) {
try{
Enumeration<String> ns_= SpringIocContextListener.getServletcontext().getAttributeNames();
while(ns_.hasMoreElements()){
name=ns_.nextElement();//从spring 配置中获取上下面名称
if(null!=name&&name.trim().length()>0&&name.matches(FrameworkServlet.SERVLET_CONTEXT_PREFIX+"*")){
context=WebApplicationContextUtils.getWebApplicationContext(SpringIocContextListener.getServletcontext(), name);
break;
}
}
}catch(Exception e){
log.warn("Spring IOC getWebApplicationContext(sc,\""+name+"\") type fail.");
}
}
if (context == null) {
try{
context=WebApplicationContextUtils.getRequiredWebApplicationContext(SpringIocContextListener.getServletcontext());
}catch(Exception e){
log.warn("Spring IOC getRequiredWebApplicationContext type fail.");
}
}
if (context == null) {
try{
context = initLocalAppContext();
}catch(Exception e){
e.printStackTrace();
log.warn("Spring IOC ClassPathXmlApplicationContext type fail.");
}
}
return context;
}
private static ApplicationContext initLocalAppContext() {
if(ToolUtils.isEmpty(springConfigFilePath)){
log.error("Spring Config FilePath is empty.");
return null;
}
ApplicationContext context = new ClassPathXmlApplicationContext(springConfigFilePath);
log.info("load " + springConfigFilePath + " success!");
return context;
}
}