为Spring扩展Application Bean 作用域

除了Singleton和Prototype两个原生Bean作用域外,早在Spring2.0版本上,就增加了具有web生命周期的bean 作用域:request、session和 global session。但不支持ServletContext(即Web中Application)作用域。尽管Singleton有一定的全局作用意义,但在Sping容器中支持Application,以IOC方式注入和访问ServletContext中的Bean对象,对于WEB开发还是很有用处的。
本文利用Spring自定义作用域机制,扩展了其bean作用域。简单的实现了对Application作用域的支持。

Holder类,使用类静态变量方式持有ServletContext
package rtl.ioc.spring;

import javax.servlet.ServletContext;
public class ApplicationHolder{
	
  private static ServletContext ctx=null;
	
  public static void setApplication(ServletContext sctx){
	  ctx=sctx;
  }
  
  public static void setApplicationAttribute(String name,Object obj){
	  ctx.setAttribute(name, obj);
  }

  public static Object getApplicationAttribute(String name) {
    return ctx.getAttribute(name);
  }
  
  public static void  removeApplicationAttribute(String name) {
	 ctx.removeAttribute(name);
  }
}

ApplicationScope实现org.springframework.beans.factory.config.Scope (Bean作用域接口)
package rtl.ioc.spring;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;

public class ApplicationScope implements Scope{
	
  public Object get(String name, ObjectFactory objectFactory){
    Object scopedObject = ApplicationHolder.getApplicationAttribute(name);
    if (scopedObject == null) {
      scopedObject = objectFactory.getObject();
      ApplicationHolder.setApplicationAttribute(name, scopedObject);
    }
    return scopedObject;
  }

  public Object remove(String name) {
	Object scopedObject = ApplicationHolder.getApplicationAttribute(name);
    if (scopedObject != null) {
    	ApplicationHolder.removeApplicationAttribute(name);
    	return scopedObject;
    }
    return null;
  }

  public void registerDestructionCallback(String name, Runnable callback){ }

  public String getConversationId() {
	return null;
  }

}

使用ServletContextListener向ApplicationHolder类注入ServletContext
package rtl.ioc.spring;

import javax.servlet.*;

public class ApplicationScopeListener implements ServletContextListener {

	public void contextInitialized(ServletContextEvent event){
		ApplicationHolder.setApplication(event.getServletContext());
	}

	public void contextDestroyed(ServletContextEvent event){}
}


使用CustomScopeConfigurer来进行声明式注册Application作用域
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="application">
                    <bean class="rtl.ioc.spring.ApplicationScope"/>
                </entry>
            </map>
        </property>
 </bean>


使用演示配置形如:
<bean id="ApplicationBean" class="demo.ApplicationBean" scope="application"></bean>











你可能感兴趣的:(java,spring,Web,bean,IOC)