使用web.xml方式加载Spring时,获取Spring context的两种方式:
1、servlet方式加载时:
【web.xml】
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext</param-value>
</init-param>
</servlet>
【jsp/servlet】
ServletContext context = getServletContext();
XmlWebApplicationContext applicationContext = (XmlWebApplicationContext) context.getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet");
DataSource dataSource=(DataSource)applicationContext.getBean("dataSource");
2、listener方式加载时:
【web.xml】
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
【jsp/servlet】
ServletContext context = getServletContext();
WebApplicationContext applicationContext = WebApplicationContextUtils
.getWebApplicationContext(context);
DataSource dataSource=(DataSource)applicationContext.getBean("dataSource");
参考地址:http://chanson.iteye.com/blog/223263
下面给出监听配置模式完整代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:config/hib-config.xml,classpath*:config/springmvc-servlet.xml</param-value>
</context-param>
<filter>
<filter-name>viewFilter</filter-name>
<filter-class>
filter.ViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>viewFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!--编码转换,正对post方式有效,get方式无效
get方式乱码解决方案,配置tomcat编码
<Connector connectionTimeout="20000" port="8888" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
参考配置地址:http://fhqiwcw.iteye.com/blog/1439665
-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:config/hib-config.xml,classpath*:config/springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
通过这种方式在servlet容器之中产生
org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet 使用dispatcherServlet加载配置文件
在sevletContext容器之中产生key为org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet ,对应WebApplicationContex
使用监听加载配置
在sevletContext容器之中产生key为org.springframework.web.context.WebApplicationContext.ROOT,对应WebApplicationContex
本次同时产生上述两种,可以不要监听加载
SpringHelper源码:
import java.io.PrintStream;
import java.lang.reflect.Field;
import javax.servlet.ServletContext;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class SpringHelper
{
private static SpringHelper instance = new SpringHelper();
private ApplicationContext applicationContext = null;
public static SpringHelper getInstance()
{
return instance;
}
public ApplicationContext getApplicationContext()
{
return this.applicationContext;
}
public void setApplicationContext(ApplicationContext applicationContext)
{
this.applicationContext = applicationContext;
}
public static Object getBean(String beanId) {
if (getInstance().getApplicationContext() == null) return null;
if (!getInstance().getApplicationContext().containsBean(beanId)) {
System.out.println("The bean [" + beanId + "] is not found!!");
return null;
}
return getInstance().getApplicationContext().getBean(beanId);
}
public static boolean containsBean(String beanId) {
return getInstance().getApplicationContext().containsBean(beanId);
}
public void initSpringFramework(ServletContext context) {
this.applicationContext = WebApplicationContextUtils.getWebApplicationContext(context);
}
public static String getBeanPropertyValue(String beanId, String propername)
{
SystemConfig config = (SystemConfig)getBean("systemConfig");
String propertyValue = config.getValue(propername);
return propertyValue;
}
public static Object getTarget(Object proxy)
throws Exception
{
if (!AopUtils.isAopProxy(proxy)) {
return proxy;
}
if (AopUtils.isJdkDynamicProxy(proxy)) {
return getJdkDynamicProxyTargetObject(proxy);
}
return getCglibProxyTargetObject(proxy);
}
private static Object getCglibProxyTargetObject(Object proxy)
throws Exception
{
Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
h.setAccessible(true);
Object dynamicAdvisedInterceptor = h.get(proxy);
Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
advised.setAccessible(true);
Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
return target;
}
private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception
{
Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
h.setAccessible(true);
AopProxy aopProxy = (AopProxy)h.get(proxy);
Field advised = aopProxy.getClass().getDeclaredField("advised");
advised.setAccessible(true);
Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();
return target;
}
}
为了让SpringHelper中拿到Spring容器,我选择一个一个Filter的init方法注入了Servlet容器
@Override
public void init(FilterConfig filterconfig) throws ServletException {
SpringHelper.getInstance().initSpringFramework(filterconfig.getServletContext());
}
然后
public static WebApplicationContext getWebApplicationContext(ServletContext sc)
{
return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
}
因为通过监听方式才会产生Servlet中以WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE为key的spring容器
所以如果通过getWebApplicationContext方法拿的话需要监听模式注入才会产生WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE为key的Spring容器