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>
【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; } }