001/* 002 * Copyright 2002-2014 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.context.support; 018 019import javax.servlet.ServletConfig; 020import javax.servlet.ServletContext; 021 022import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 023import org.springframework.beans.factory.support.DefaultListableBeanFactory; 024import org.springframework.context.support.GenericApplicationContext; 025import org.springframework.core.env.ConfigurableEnvironment; 026import org.springframework.core.io.Resource; 027import org.springframework.core.io.support.ResourcePatternResolver; 028import org.springframework.ui.context.Theme; 029import org.springframework.ui.context.ThemeSource; 030import org.springframework.ui.context.support.UiApplicationContextUtils; 031import org.springframework.util.ObjectUtils; 032import org.springframework.util.StringUtils; 033import org.springframework.web.context.ConfigurableWebApplicationContext; 034import org.springframework.web.context.ConfigurableWebEnvironment; 035import org.springframework.web.context.ServletContextAware; 036 037/** 038 * Subclass of {@link GenericApplicationContext}, suitable for web environments. 039 * 040 * <p>Implements the 041 * {@link org.springframework.web.context.ConfigurableWebApplicationContext}, 042 * but is not intended for declarative setup in {@code web.xml}. Instead, 043 * it is designed for programmatic setup, for example for building nested contexts or 044 * for use within Spring 3.1 {@link org.springframework.web.WebApplicationInitializer}s. 045 * 046 * <p><b>If you intend to implement a WebApplicationContext that reads bean definitions 047 * from configuration files, consider deriving from AbstractRefreshableWebApplicationContext, 048 * reading the bean definitions in an implementation of the {@code loadBeanDefinitions} 049 * method.</b> 050 * 051 * <p>Interprets resource paths as servlet context resources, i.e. as paths beneath 052 * the web application root. Absolute paths, e.g. for files outside the web app root, 053 * can be accessed via "file:" URLs, as implemented by AbstractApplicationContext. 054 * 055 * <p>In addition to the special beans detected by 056 * {@link org.springframework.context.support.AbstractApplicationContext}, 057 * this class detects a ThemeSource bean in the context, with the name "themeSource". 058 * 059 * @author Juergen Hoeller 060 * @author Chris Beams 061 * @since 1.2 062 */ 063public class GenericWebApplicationContext extends GenericApplicationContext 064 implements ConfigurableWebApplicationContext, ThemeSource { 065 066 private ServletContext servletContext; 067 068 private ThemeSource themeSource; 069 070 071 /** 072 * Create a new GenericWebApplicationContext. 073 * @see #setServletContext 074 * @see #registerBeanDefinition 075 * @see #refresh 076 */ 077 public GenericWebApplicationContext() { 078 super(); 079 } 080 081 /** 082 * Create a new GenericWebApplicationContext for the given ServletContext. 083 * @param servletContext the ServletContext to run in 084 * @see #registerBeanDefinition 085 * @see #refresh 086 */ 087 public GenericWebApplicationContext(ServletContext servletContext) { 088 this.servletContext = servletContext; 089 } 090 091 /** 092 * Create a new GenericWebApplicationContext with the given DefaultListableBeanFactory. 093 * @param beanFactory the DefaultListableBeanFactory instance to use for this context 094 * @see #setServletContext 095 * @see #registerBeanDefinition 096 * @see #refresh 097 */ 098 public GenericWebApplicationContext(DefaultListableBeanFactory beanFactory) { 099 super(beanFactory); 100 } 101 102 /** 103 * Create a new GenericWebApplicationContext with the given DefaultListableBeanFactory. 104 * @param beanFactory the DefaultListableBeanFactory instance to use for this context 105 * @param servletContext the ServletContext to run in 106 * @see #registerBeanDefinition 107 * @see #refresh 108 */ 109 public GenericWebApplicationContext(DefaultListableBeanFactory beanFactory, ServletContext servletContext) { 110 super(beanFactory); 111 this.servletContext = servletContext; 112 } 113 114 115 /** 116 * Set the ServletContext that this WebApplicationContext runs in. 117 */ 118 @Override 119 public void setServletContext(ServletContext servletContext) { 120 this.servletContext = servletContext; 121 } 122 123 @Override 124 public ServletContext getServletContext() { 125 return this.servletContext; 126 } 127 128 @Override 129 public String getApplicationName() { 130 return (this.servletContext != null ? this.servletContext.getContextPath() : ""); 131 } 132 133 /** 134 * Create and return a new {@link StandardServletEnvironment}. 135 */ 136 @Override 137 protected ConfigurableEnvironment createEnvironment() { 138 return new StandardServletEnvironment(); 139 } 140 141 /** 142 * Register ServletContextAwareProcessor. 143 * @see ServletContextAwareProcessor 144 */ 145 @Override 146 protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { 147 beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext)); 148 beanFactory.ignoreDependencyInterface(ServletContextAware.class); 149 150 WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); 151 WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext); 152 } 153 154 /** 155 * This implementation supports file paths beneath the root of the ServletContext. 156 * @see ServletContextResource 157 */ 158 @Override 159 protected Resource getResourceByPath(String path) { 160 return new ServletContextResource(this.servletContext, path); 161 } 162 163 /** 164 * This implementation supports pattern matching in unexpanded WARs too. 165 * @see ServletContextResourcePatternResolver 166 */ 167 @Override 168 protected ResourcePatternResolver getResourcePatternResolver() { 169 return new ServletContextResourcePatternResolver(this); 170 } 171 172 /** 173 * Initialize the theme capability. 174 */ 175 @Override 176 protected void onRefresh() { 177 this.themeSource = UiApplicationContextUtils.initThemeSource(this); 178 } 179 180 /** 181 * {@inheritDoc} 182 * <p>Replace {@code Servlet}-related property sources. 183 */ 184 @Override 185 protected void initPropertySources() { 186 ConfigurableEnvironment env = getEnvironment(); 187 if (env instanceof ConfigurableWebEnvironment) { 188 ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null); 189 } 190 } 191 192 @Override 193 public Theme getTheme(String themeName) { 194 return this.themeSource.getTheme(themeName); 195 } 196 197 198 // --------------------------------------------------------------------- 199 // Pseudo-implementation of ConfigurableWebApplicationContext 200 // --------------------------------------------------------------------- 201 202 @Override 203 public void setServletConfig(ServletConfig servletConfig) { 204 // no-op 205 } 206 207 @Override 208 public ServletConfig getServletConfig() { 209 throw new UnsupportedOperationException( 210 "GenericWebApplicationContext does not support getServletConfig()"); 211 } 212 213 @Override 214 public void setNamespace(String namespace) { 215 // no-op 216 } 217 218 @Override 219 public String getNamespace() { 220 throw new UnsupportedOperationException( 221 "GenericWebApplicationContext does not support getNamespace()"); 222 } 223 224 @Override 225 public void setConfigLocation(String configLocation) { 226 if (StringUtils.hasText(configLocation)) { 227 throw new UnsupportedOperationException( 228 "GenericWebApplicationContext does not support setConfigLocation(). " + 229 "Do you still have an 'contextConfigLocations' init-param set?"); 230 } 231 } 232 233 @Override 234 public void setConfigLocations(String... configLocations) { 235 if (!ObjectUtils.isEmpty(configLocations)) { 236 throw new UnsupportedOperationException( 237 "GenericWebApplicationContext does not support setConfigLocations(). " + 238 "Do you still have an 'contextConfigLocations' init-param set?"); 239 } 240 } 241 242 @Override 243 public String[] getConfigLocations() { 244 throw new UnsupportedOperationException( 245 "GenericWebApplicationContext does not support getConfigLocations()"); 246 } 247 248}