使用web.xml方式加载Spring时,获取Spring context的两种方式

使用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容器

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值