renamed "contextProperties" attribute to "contextParameters" (matching web.xml naming); "contextParameters" contains Servlet/PortletConfig parameters as well; added default "servletContext" and "servletConfig" environment beans; added default "portletContext" and "portletConfig" environment beans; added default web scope "application", wrapping a ServletContext/PortletContext; MockPortletSession supports destruction of session attributes on invalidation

This commit is contained in:
Juergen Hoeller
2009-05-05 12:12:01 +00:00
parent 0a0938fdd6
commit b15e77d5d0
26 changed files with 1123 additions and 70 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,13 @@ import org.springframework.context.ConfigurableApplicationContext;
*/
public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {
/**
* Name of the ServletConfig environment bean in the factory.
* @see javax.servlet.ServletConfig
*/
String SERVLET_CONFIG_BEAN_NAME = "servletConfig";
/**
* Set the ServletContext for this web application context.
* <p>Does not cause an initialization of the context: refresh needs to be

View File

@@ -0,0 +1,77 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.context;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
/**
* Web application listener that cleans up remaining disposable attributes
* in the ServletContext, i.e. attributes which implement {@link DisposableBean}
* and haven't been removed before. This is typically used for destroying objects
* in "application" scope, for which the lifecycle implies destruction at the
* very end of the web application's shutdown phase.
*
* @author Juergen Hoeller
* @since 3.0
* @see org.springframework.web.context.support.ServletContextScope
* @see ContextLoaderListener
*/
public class ContextCleanupListener implements ServletContextListener {
private static final Log logger = LogFactory.getLog(ContextCleanupListener.class);
public void contextInitialized(ServletContextEvent event) {
}
public void contextDestroyed(ServletContextEvent event) {
cleanupAttributes(event.getServletContext());
}
/**
* Find all ServletContext attributes which implement {@link DisposableBean}
* and destroy them, removing all affected ServletContext attributes eventually.
* @param sc the ServletContext to check
*/
static void cleanupAttributes(ServletContext sc) {
Enumeration attrNames = sc.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (attrName.startsWith("org.springframework.")) {
Object attrValue = sc.getAttribute(attrName);
if (attrValue instanceof DisposableBean) {
try {
((DisposableBean) attrValue).destroy();
}
catch (Throwable ex) {
logger.error("Couldn't invoke destroy method of attribute with name '" + attrName + "'", ex);
}
}
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -269,7 +269,7 @@ public class ContextLoader {
String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
if (contextClassName != null) {
try {
return ClassUtils.forName(contextClassName);
return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException(

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,8 +20,8 @@ import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* Bootstrap listener to start up Spring's root {@link WebApplicationContext}.
* Simply delegates to {@link ContextLoader}.
* Bootstrap listener to start up and shut down Spring's root {@link WebApplicationContext}.
* Simply delegates to {@link ContextLoader} as well as to {@link ContextCleanupListener}.
*
* <p>This listener should be registered after
* {@link org.springframework.web.util.Log4jConfigListener}
@@ -77,6 +77,7 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte
if (this.contextLoader != null) {
this.contextLoader.closeWebApplicationContext(event.getServletContext());
}
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -72,14 +72,30 @@ public interface WebApplicationContext extends ApplicationContext {
String SCOPE_GLOBAL_SESSION = "globalSession";
/**
* Name of the ServletContext init-params environment bean in the factory.
* @see javax.servlet.ServletContext#getInitParameterNames()
* @see javax.servlet.ServletContext#getInitParameter(String)
* Scope identifier for the global web application scope: "application".
* Supported in addition to the standard scopes "singleton" and "prototype".
*/
String CONTEXT_PROPERTIES_BEAN_NAME = "contextProperties";
String SCOPE_APPLICATION = "application";
/**
* Name of the ServletContext attributes environment bean in the factory.
* Name of the ServletContext environment bean in the factory.
* @see javax.servlet.ServletContext
*/
String SERVLET_CONTEXT_BEAN_NAME = "servletContext";
/**
* Name of the ServletContext/PortletContext init-params environment bean in the factory.
* <p>Note: Possibly merged with ServletConfig/PortletConfig parameters.
* ServletConfig parameters override ServletContext parameters of the same name.
* @see javax.servlet.ServletContext#getInitParameterNames()
* @see javax.servlet.ServletContext#getInitParameter(String)
* @see javax.servlet.ServletConfig#getInitParameterNames()
* @see javax.servlet.ServletConfig#getInitParameter(String)
*/
String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";
/**
* Name of the ServletContext/PortletContext attributes environment bean in the factory.
* @see javax.servlet.ServletContext#getAttributeNames()
* @see javax.servlet.ServletContext#getAttribute(String)
*/
@@ -88,6 +104,7 @@ public interface WebApplicationContext extends ApplicationContext {
/**
* Return the standard Servlet API ServletContext for this application.
* <p>Also available for a Portlet application, in addition to the PortletContext.
*/
ServletContext getServletContext();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -139,11 +139,9 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
beanFactory.registerResolvableDependency(ServletContext.class, this.servletContext);
beanFactory.registerResolvableDependency(ServletConfig.class, this.servletConfig);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,6 +71,16 @@ public class GenericWebApplicationContext extends GenericApplicationContext
super();
}
/**
* Create a new GenericWebApplicationContext for the given ServletContext.
* @param servletContext the ServletContext to run in
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericWebApplicationContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
/**
* Create a new GenericWebApplicationContext with the given DefaultListableBeanFactory.
* @param beanFactory the DefaultListableBeanFactory instance to use for this context
@@ -82,6 +92,18 @@ public class GenericWebApplicationContext extends GenericApplicationContext
super(beanFactory);
}
/**
* Create a new GenericWebApplicationContext with the given DefaultListableBeanFactory.
* @param beanFactory the DefaultListableBeanFactory instance to use for this context
* @param servletContext the ServletContext to run in
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericWebApplicationContext(DefaultListableBeanFactory beanFactory, ServletContext servletContext) {
super(beanFactory);
this.servletContext = servletContext;
}
/**
* Set the ServletContext that this WebApplicationContext runs in.
@@ -103,9 +125,8 @@ public class GenericWebApplicationContext extends GenericApplicationContext
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.registerResolvableDependency(ServletContext.class, this.servletContext);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}

View File

@@ -30,10 +30,15 @@ import org.springframework.web.context.ServletContextAware;
* the startup of the Spring application context. Typically, such
* attributes will have been put there by third-party web frameworks.
* In a purely Spring-based web application, no such linking in of
* ServletContext attrutes will be necessary.
* ServletContext attributes will be necessary.
*
* <p><b>NOTE:</b> As of Spring 3.0, you may also use the "contextAttributes" default
* bean which is of type Map, and dereference it using an "#{contextAttributes.myKey}"
* expression to access a specific attribute by name.
*
* @author Juergen Hoeller
* @since 1.1.4
* @see org.springframework.web.context.WebApplicationContext#CONTEXT_ATTRIBUTES_BEAN_NAME
* @see ServletContextParameterFactoryBean
*/
public class ServletContextAttributeFactoryBean implements FactoryBean<Object>, ServletContextAware {
@@ -52,7 +57,7 @@ public class ServletContextAttributeFactoryBean implements FactoryBean<Object>,
public void setServletContext(ServletContext servletContext) {
if (this.attributeName == null) {
throw new IllegalArgumentException("attributeName is required");
throw new IllegalArgumentException("Property 'attributeName' is required");
}
this.attribute = servletContext.getAttribute(this.attributeName);
if (this.attribute == null) {

View File

@@ -39,7 +39,11 @@ import org.springframework.web.context.ServletContextAware;
* @see javax.servlet.ServletContext
* @see org.springframework.web.context.ServletContextAware
* @see ServletContextAttributeFactoryBean
* @see org.springframework.web.context.WebApplicationContext#SERVLET_CONTEXT_BEAN_NAME
* @deprecated as of Spring 3.0, since "servletContext" is now available
* as a default bean in every WebApplicationContext
*/
@Deprecated
public class ServletContextFactoryBean implements FactoryBean<ServletContext>, ServletContextAware {
private ServletContext servletContext;

View File

@@ -27,8 +27,13 @@ import org.springframework.web.context.ServletContextAware;
* Exposes that ServletContext init parameter when used as bean reference,
* effectively making it available as named Spring bean instance.
*
* <p><b>NOTE:</b> As of Spring 3.0, you may also use the "contextParameters" default
* bean which is of type Map, and dereference it using an "#{contextParameters.myKey}"
* expression to access a specific parameter by name.
*
* @author Juergen Hoeller
* @since 1.2.4
* @see org.springframework.web.context.WebApplicationContext#CONTEXT_PARAMETERS_BEAN_NAME
* @see ServletContextAttributeFactoryBean
*/
public class ServletContextParameterFactoryBean implements FactoryBean<String>, ServletContextAware {

View File

@@ -0,0 +1,111 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.context.support;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.util.Assert;
/**
* {@link Scope} wrapper for a ServletContext, i.e. for global web application attributes.
*
* <p>This differs from traditional Spring singletons in that it exposes attributes in the
* ServletContext. Those attributes will get destroyed whenever the entire application
* shuts down, which might be earlier or later than the shutdown of the containing Spring
* ApplicationContext.
*
* <p>The associated destruction mechanism relies on a
* {@link org.springframework.web.context.ContextCleanupListener} being registered in
* <code>web.xml</code>. Note that {@link org.springframework.web.context.ContextLoaderListener}
* includes ContextCleanupListener's functionality.
*
* <p>This scope is registered as default scope with key
* {@link org.springframework.web.context.WebApplicationContext#SCOPE_APPLICATION "application"}.
*
* @author Juergen Hoeller
* @since 3.0
* @see org.springframework.web.context.ContextCleanupListener
*/
public class ServletContextScope implements Scope, DisposableBean {
private final ServletContext servletContext;
private final Map<String, Runnable> destructionCallbacks = new LinkedHashMap<String, Runnable>();
/**
* Create a new Scope wrapper for the given ServletContext.
* @param servletContext the ServletContext to wrap
*/
public ServletContextScope(ServletContext servletContext) {
Assert.notNull(servletContext, "ServletContext must not be null");
this.servletContext = servletContext;
}
public Object get(String name, ObjectFactory<?> objectFactory) {
Object scopedObject = this.servletContext.getAttribute(name);
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
this.servletContext.setAttribute(name, scopedObject);
}
return scopedObject;
}
public Object remove(String name) {
Object scopedObject = this.servletContext.getAttribute(name);
if (scopedObject != null) {
this.servletContext.removeAttribute(name);
this.destructionCallbacks.remove(name);
return scopedObject;
}
else {
return null;
}
}
public void registerDestructionCallback(String name, Runnable callback) {
this.destructionCallbacks.put(name, callback);
}
public Object resolveContextualObject(String key) {
return null;
}
public String getConversationId() {
return null;
}
/**
* Invoke all registered destruction callbacks.
* To be called on ServletContext shutdown.
* @see org.springframework.web.context.ContextCleanupListener
*/
public void destroy() {
for (Runnable runnable : this.destructionCallbacks.values()) {
runnable.run();
}
this.destructionCallbacks.clear();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,8 +29,6 @@ import org.springframework.ui.context.support.UiApplicationContextUtils;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.ServletConfigAware;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.request.RequestScope;
import org.springframework.web.context.request.SessionScope;
/**
* Static {@link org.springframework.web.context.WebApplicationContext}
@@ -137,11 +135,9 @@ public class StaticWebApplicationContext extends StaticApplicationContext
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
beanFactory.registerResolvableDependency(ServletContext.class, this.servletContext);
beanFactory.registerResolvableDependency(ServletConfig.class, this.servletConfig);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
/**

View File

@@ -20,6 +20,9 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;
@@ -27,6 +30,8 @@ import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
@@ -49,10 +54,15 @@ import org.springframework.web.context.request.SessionScope;
* @see org.springframework.web.servlet.FrameworkServlet
* @see org.springframework.web.servlet.DispatcherServlet
* @see org.springframework.web.jsf.FacesContextUtils
* @see org.springframework.web.jsf.DelegatingVariableResolver
* @see org.springframework.web.jsf.SpringBeanVariableResolver
* @see org.springframework.web.jsf.el.SpringBeanFacesELResolver
*/
public abstract class WebApplicationContextUtils {
private static final boolean jsfPresent =
ClassUtils.isPresent("javax.faces.context.FacesContext", RequestContextHolder.class.getClassLoader());
/**
* Find the root WebApplicationContext for this web application, which is
* typically loaded via {@link org.springframework.web.context.ContextLoaderListener}.
@@ -64,7 +74,7 @@ public abstract class WebApplicationContextUtils {
* @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
*/
public static WebApplicationContext getRequiredWebApplicationContext(ServletContext sc)
throws IllegalStateException {
throws IllegalStateException {
WebApplicationContext wac = getWebApplicationContext(sc);
if (wac == null) {
@@ -115,14 +125,30 @@ public abstract class WebApplicationContextUtils {
/**
* Register web-specific scopes with the given BeanFactory,
* as used by the WebApplicationContext.
* Register web-specific scopes ("request", "session", "globalSession")
* with the given BeanFactory, as used by the WebApplicationContext.
* @param beanFactory the BeanFactory to configure
*/
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
registerWebApplicationScopes(beanFactory, null);
}
/**
* Register web-specific scopes ("request", "session", "globalSession", "application")
* with the given BeanFactory, as used by the WebApplicationContext.
* @param beanFactory the BeanFactory to configure
* @param sc the ServletContext that we're running within
*/
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, ServletContext sc) {
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope(false));
beanFactory.registerScope(WebApplicationContext.SCOPE_GLOBAL_SESSION, new SessionScope(true));
if (sc != null) {
ServletContextScope appScope = new ServletContextScope(sc);
beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
// Register as ServletContext attribute, for ContextCleanupListener to detect it.
sc.setAttribute(ServletContextScope.class.getName(), appScope);
}
beanFactory.registerResolvableDependency(ServletRequest.class, new ObjectFactory<ServletRequest>() {
public ServletRequest getObject() {
@@ -142,16 +168,41 @@ public abstract class WebApplicationContextUtils {
return ((ServletRequestAttributes) requestAttr).getRequest().getSession();
}
});
if (jsfPresent) {
FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
}
}
/**
* Register web-specific environment beans with the given BeanFactory,
* as used by the WebApplicationContext.
* Register web-specific environment beans ("contextParameters", "contextAttributes")
* with the given BeanFactory, as used by the WebApplicationContext.
* @param bf the BeanFactory to configure
* @param sc the ServletContext that we're running within
*/
static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf, ServletContext sc) {
if (!bf.containsBean(WebApplicationContext.CONTEXT_PROPERTIES_BEAN_NAME)) {
public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf, ServletContext sc) {
registerEnvironmentBeans(bf, sc, null);
}
/**
* Register web-specific environment beans ("contextParameters", "contextAttributes")
* with the given BeanFactory, as used by the WebApplicationContext.
* @param bf the BeanFactory to configure
* @param sc the ServletContext that we're running within
* @param config the ServletConfig of the containing Portlet
*/
public static void registerEnvironmentBeans(
ConfigurableListableBeanFactory bf, ServletContext sc, ServletConfig config) {
if (sc != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {
bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, sc);
}
if (config != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {
bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, config);
}
if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {
Map<String, String> parameterMap = new HashMap<String, String>();
if (sc != null) {
Enumeration paramNameEnum = sc.getInitParameterNames();
@@ -160,7 +211,14 @@ public abstract class WebApplicationContextUtils {
parameterMap.put(paramName, sc.getInitParameter(paramName));
}
}
bf.registerSingleton(WebApplicationContext.CONTEXT_PROPERTIES_BEAN_NAME,
if (config != null) {
Enumeration paramNameEnum = config.getInitParameterNames();
while (paramNameEnum.hasMoreElements()) {
String paramName = (String) paramNameEnum.nextElement();
parameterMap.put(paramName, config.getInitParameter(paramName));
}
}
bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,
Collections.unmodifiableMap(parameterMap));
}
@@ -178,4 +236,24 @@ public abstract class WebApplicationContextUtils {
}
}
/**
* Inner class to avoid hard-coded JSF dependency.
*/
private static class FacesDependencyRegistrar {
public static void registerFacesDependencies(ConfigurableListableBeanFactory beanFactory) {
beanFactory.registerResolvableDependency(FacesContext.class, new ObjectFactory<FacesContext>() {
public FacesContext getObject() {
return FacesContext.getCurrentInstance();
}
});
beanFactory.registerResolvableDependency(ExternalContext.class, new ObjectFactory<ExternalContext>() {
public ExternalContext getObject() {
return FacesContext.getCurrentInstance().getExternalContext();
}
});
}
}
}