GenericFilterBean lazily initializes its default environment
Alignment with HttpServletBean; consistent use of EnvironmentCapable. Issue: SPR-15469
This commit is contained in:
		
							parent
							
								
									04f0f137e6
								
							
						
					
					
						commit
						1ea54eb2c6
					
				|  | @ -1,5 +1,5 @@ | ||||||
| /* | /* | ||||||
|  * Copyright 2002-2016 the original author or authors. |  * Copyright 2002-2017 the original author or authors. | ||||||
|  * |  * | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  * you may not use this file except in compliance with the License. |  * you may not use this file except in compliance with the License. | ||||||
|  | @ -102,13 +102,6 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life | ||||||
| 	 */ | 	 */ | ||||||
| 	void setParent(ApplicationContext parent); | 	void setParent(ApplicationContext parent); | ||||||
| 
 | 
 | ||||||
| 	/** |  | ||||||
| 	 * Return the Environment for this application context in configurable form. |  | ||||||
| 	 * @since 3.1 |  | ||||||
| 	 */ |  | ||||||
| 	@Override |  | ||||||
| 	ConfigurableEnvironment getEnvironment(); |  | ||||||
| 
 |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Set the {@code Environment} for this application context. | 	 * Set the {@code Environment} for this application context. | ||||||
| 	 * @param environment the new environment | 	 * @param environment the new environment | ||||||
|  | @ -116,6 +109,14 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life | ||||||
| 	 */ | 	 */ | ||||||
| 	void setEnvironment(ConfigurableEnvironment environment); | 	void setEnvironment(ConfigurableEnvironment environment); | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Return the {@code Environment} for this application context in configurable | ||||||
|  | 	 * form, allowing for further customization. | ||||||
|  | 	 * @since 3.1 | ||||||
|  | 	 */ | ||||||
|  | 	@Override | ||||||
|  | 	ConfigurableEnvironment getEnvironment(); | ||||||
|  | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Add a new BeanFactoryPostProcessor that will get applied to the internal | 	 * Add a new BeanFactoryPostProcessor that will get applied to the internal | ||||||
| 	 * bean factory of this application context on refresh, before any of the | 	 * bean factory of this application context on refresh, before any of the | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /* | /* | ||||||
|  * Copyright 2002-2011 the original author or authors. |  * Copyright 2002-2017 the original author or authors. | ||||||
|  * |  * | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  * you may not use this file except in compliance with the License. |  * you may not use this file except in compliance with the License. | ||||||
|  | @ -25,11 +25,12 @@ import org.springframework.core.env.Environment; | ||||||
|  * |  * | ||||||
|  * @author Chris Beams |  * @author Chris Beams | ||||||
|  * @since 3.1 |  * @since 3.1 | ||||||
|  |  * @see org.springframework.core.env.EnvironmentCapable | ||||||
|  */ |  */ | ||||||
| public interface EnvironmentAware extends Aware { | public interface EnvironmentAware extends Aware { | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Set the {@code Environment} that this object runs in. | 	 * Set the {@code Environment} that this component runs in. | ||||||
| 	 */ | 	 */ | ||||||
| 	void setEnvironment(Environment environment); | 	void setEnvironment(Environment environment); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -280,8 +280,22 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * {@inheritDoc} | 	 * Set the {@code Environment} for this application context. | ||||||
| 	 * <p>If {@code null}, a new environment will be initialized via | 	 * <p>Default value is determined by {@link #createEnvironment()}. Replacing the | ||||||
|  | 	 * default with this method is one option but configuration through {@link | ||||||
|  | 	 * #getEnvironment()} should also be considered. In either case, such modifications | ||||||
|  | 	 * should be performed <em>before</em> {@link #refresh()}. | ||||||
|  | 	 * @see org.springframework.context.support.AbstractApplicationContext#createEnvironment | ||||||
|  | 	 */ | ||||||
|  | 	@Override | ||||||
|  | 	public void setEnvironment(ConfigurableEnvironment environment) { | ||||||
|  | 		this.environment = environment; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Return the {@code Environment} for this application context in configurable | ||||||
|  | 	 * form, allowing for further customization. | ||||||
|  | 	 * <p>If none specified, a default environment will be initialized via | ||||||
| 	 * {@link #createEnvironment()}. | 	 * {@link #createEnvironment()}. | ||||||
| 	 */ | 	 */ | ||||||
| 	@Override | 	@Override | ||||||
|  | @ -293,16 +307,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * {@inheritDoc} | 	 * Create and return a new {@link StandardEnvironment}. | ||||||
| 	 * <p>Default value is determined by {@link #createEnvironment()}. Replacing the | 	 * <p>Subclasses may override this method in order to supply | ||||||
| 	 * default with this method is one option but configuration through {@link | 	 * a custom {@link ConfigurableEnvironment} implementation. | ||||||
| 	 * #getEnvironment()} should also be considered. In either case, such modifications |  | ||||||
| 	 * should be performed <em>before</em> {@link #refresh()}. |  | ||||||
| 	 * @see org.springframework.context.support.AbstractApplicationContext#createEnvironment |  | ||||||
| 	 */ | 	 */ | ||||||
| 	@Override | 	protected ConfigurableEnvironment createEnvironment() { | ||||||
| 	public void setEnvironment(ConfigurableEnvironment environment) { | 		return new StandardEnvironment(); | ||||||
| 		this.environment = environment; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
|  | @ -443,7 +453,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader | ||||||
| 	//--------------------------------------------------------------------- | 	//--------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * {@inheritDoc} | 	 * Set the parent of this application context. | ||||||
| 	 * <p>The parent {@linkplain ApplicationContext#getEnvironment() environment} is | 	 * <p>The parent {@linkplain ApplicationContext#getEnvironment() environment} is | ||||||
| 	 * {@linkplain ConfigurableEnvironment#merge(ConfigurableEnvironment) merged} with | 	 * {@linkplain ConfigurableEnvironment#merge(ConfigurableEnvironment) merged} with | ||||||
| 	 * this (child) application context environment if the parent is non-{@code null} and | 	 * this (child) application context environment if the parent is non-{@code null} and | ||||||
|  | @ -494,15 +504,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader | ||||||
| 		return this.applicationListeners; | 		return this.applicationListeners; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** |  | ||||||
| 	 * Create and return a new {@link StandardEnvironment}. |  | ||||||
| 	 * <p>Subclasses may override this method in order to supply |  | ||||||
| 	 * a custom {@link ConfigurableEnvironment} implementation. |  | ||||||
| 	 */ |  | ||||||
| 	protected ConfigurableEnvironment createEnvironment() { |  | ||||||
| 		return new StandardEnvironment(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public void refresh() throws BeansException, IllegalStateException { | 	public void refresh() throws BeansException, IllegalStateException { | ||||||
| 		synchronized (this.startupShutdownMonitor) { | 		synchronized (this.startupShutdownMonitor) { | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /* | /* | ||||||
|  * Copyright 2002-2013 the original author or authors. |  * Copyright 2002-2017 the original author or authors. | ||||||
|  * |  * | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  * you may not use this file except in compliance with the License. |  * you may not use this file except in compliance with the License. | ||||||
|  | @ -41,7 +41,8 @@ package org.springframework.core.env; | ||||||
| public interface EnvironmentCapable { | public interface EnvironmentCapable { | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Return the {@link Environment} associated with this component. | 	 * Return the {@link Environment} associated with this component | ||||||
|  | 	 * (may be {@code null} or a default environment). | ||||||
| 	 */ | 	 */ | ||||||
| 	Environment getEnvironment(); | 	Environment getEnvironment(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /* | /* | ||||||
|  * Copyright 2002-2016 the original author or authors. |  * Copyright 2002-2017 the original author or authors. | ||||||
|  * |  * | ||||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  * you may not use this file except in compliance with the License. |  * you may not use this file except in compliance with the License. | ||||||
|  | @ -38,10 +38,12 @@ import org.springframework.beans.factory.DisposableBean; | ||||||
| import org.springframework.beans.factory.InitializingBean; | import org.springframework.beans.factory.InitializingBean; | ||||||
| import org.springframework.context.EnvironmentAware; | import org.springframework.context.EnvironmentAware; | ||||||
| import org.springframework.core.env.Environment; | import org.springframework.core.env.Environment; | ||||||
|  | import org.springframework.core.env.EnvironmentCapable; | ||||||
| import org.springframework.core.io.Resource; | import org.springframework.core.io.Resource; | ||||||
| import org.springframework.core.io.ResourceEditor; | import org.springframework.core.io.ResourceEditor; | ||||||
| import org.springframework.core.io.ResourceLoader; | import org.springframework.core.io.ResourceLoader; | ||||||
| import org.springframework.util.Assert; | import org.springframework.util.Assert; | ||||||
|  | import org.springframework.util.CollectionUtils; | ||||||
| import org.springframework.util.StringUtils; | import org.springframework.util.StringUtils; | ||||||
| import org.springframework.web.context.ServletContextAware; | import org.springframework.web.context.ServletContextAware; | ||||||
| import org.springframework.web.context.support.ServletContextResourceLoader; | import org.springframework.web.context.support.ServletContextResourceLoader; | ||||||
|  | @ -75,25 +77,21 @@ import org.springframework.web.util.NestedServletException; | ||||||
|  * @see #initFilterBean |  * @see #initFilterBean | ||||||
|  * @see #doFilter |  * @see #doFilter | ||||||
|  */ |  */ | ||||||
| public abstract class GenericFilterBean implements | public abstract class GenericFilterBean implements Filter, BeanNameAware, EnvironmentAware, | ||||||
| 		Filter, BeanNameAware, EnvironmentAware, ServletContextAware, InitializingBean, DisposableBean { | 		EnvironmentCapable, ServletContextAware, InitializingBean, DisposableBean { | ||||||
| 
 | 
 | ||||||
| 	/** Logger available to subclasses */ | 	/** Logger available to subclasses */ | ||||||
| 	protected final Log logger = LogFactory.getLog(getClass()); | 	protected final Log logger = LogFactory.getLog(getClass()); | ||||||
| 
 | 
 | ||||||
| 	/** | 	private String beanName; | ||||||
| 	 * Set of required properties (Strings) that must be supplied as | 
 | ||||||
| 	 * config parameters to this filter. | 	private Environment environment; | ||||||
| 	 */ | 
 | ||||||
| 	private final Set<String> requiredProperties = new HashSet<>(); | 	private ServletContext servletContext; | ||||||
| 
 | 
 | ||||||
| 	private FilterConfig filterConfig; | 	private FilterConfig filterConfig; | ||||||
| 
 | 
 | ||||||
| 	private String beanName; | 	private final Set<String> requiredProperties = new HashSet<>(4); | ||||||
| 
 |  | ||||||
| 	private Environment environment = new StandardServletEnvironment(); |  | ||||||
| 
 |  | ||||||
| 	private ServletContext servletContext; |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
|  | @ -104,24 +102,47 @@ public abstract class GenericFilterBean implements | ||||||
| 	 * @see #getFilterName() | 	 * @see #getFilterName() | ||||||
| 	 */ | 	 */ | ||||||
| 	@Override | 	@Override | ||||||
| 	public final void setBeanName(String beanName) { | 	public void setBeanName(String beanName) { | ||||||
| 		this.beanName = beanName; | 		this.beanName = beanName; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * {@inheritDoc} | 	 * Set the {@code Environment} that this filter runs in. | ||||||
| 	 * <p>Any environment set here overrides the {@link StandardServletEnvironment} | 	 * <p>Any environment set here overrides the {@link StandardServletEnvironment} | ||||||
| 	 * provided by default. | 	 * provided by default. | ||||||
| 	 * <p>This {@code Environment} object is used only for resolving placeholders in | 	 * <p>This {@code Environment} object is used only for resolving placeholders in | ||||||
| 	 * resource paths passed into init-parameters for this filter. If no init-params are | 	 * resource paths passed into init-parameters for this filter. If no init-params are | ||||||
| 	 * used, this {@code Environment} can be essentially ignored. | 	 * used, this {@code Environment} can be essentially ignored. | ||||||
| 	 * @see #init(FilterConfig) |  | ||||||
| 	 */ | 	 */ | ||||||
| 	@Override | 	@Override | ||||||
| 	public void setEnvironment(Environment environment) { | 	public void setEnvironment(Environment environment) { | ||||||
| 		this.environment = environment; | 		this.environment = environment; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Return the {@link Environment} associated with this filter. | ||||||
|  | 	 * <p>If none specified, a default environment will be initialized via | ||||||
|  | 	 * {@link #createEnvironment()}. | ||||||
|  | 	 * @since 4.3.9 | ||||||
|  | 	 */ | ||||||
|  | 	@Override | ||||||
|  | 	public Environment getEnvironment() { | ||||||
|  | 		if (this.environment == null) { | ||||||
|  | 			this.environment = createEnvironment(); | ||||||
|  | 		} | ||||||
|  | 		return this.environment; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Create and return a new {@link StandardServletEnvironment}. | ||||||
|  | 	 * <p>Subclasses may override this in order to configure the environment or | ||||||
|  | 	 * specialize the environment type returned. | ||||||
|  | 	 * @since 4.3.9 | ||||||
|  | 	 */ | ||||||
|  | 	protected Environment createEnvironment() { | ||||||
|  | 		return new StandardServletEnvironment(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Stores the ServletContext that the bean factory runs in. | 	 * Stores the ServletContext that the bean factory runs in. | ||||||
| 	 * <p>Only relevant in case of initialization as bean, to have a ServletContext | 	 * <p>Only relevant in case of initialization as bean, to have a ServletContext | ||||||
|  | @ -130,7 +151,7 @@ public abstract class GenericFilterBean implements | ||||||
| 	 * @see #getServletContext() | 	 * @see #getServletContext() | ||||||
| 	 */ | 	 */ | ||||||
| 	@Override | 	@Override | ||||||
| 	public final void setServletContext(ServletContext servletContext) { | 	public void setServletContext(ServletContext servletContext) { | ||||||
| 		this.servletContext = servletContext; | 		this.servletContext = servletContext; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -147,6 +168,16 @@ public abstract class GenericFilterBean implements | ||||||
| 		initFilterBean(); | 		initFilterBean(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Subclasses may override this to perform custom filter shutdown. | ||||||
|  | 	 * <p>Note: This method will be called from standard filter destruction | ||||||
|  | 	 * as well as filter bean destruction in a Spring application context. | ||||||
|  | 	 * <p>This default implementation is empty. | ||||||
|  | 	 */ | ||||||
|  | 	@Override | ||||||
|  | 	public void destroy() { | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Subclasses can invoke this method to specify that this property | 	 * Subclasses can invoke this method to specify that this property | ||||||
|  | @ -180,19 +211,25 @@ public abstract class GenericFilterBean implements | ||||||
| 		this.filterConfig = filterConfig; | 		this.filterConfig = filterConfig; | ||||||
| 
 | 
 | ||||||
| 		// Set bean properties from init parameters. | 		// Set bean properties from init parameters. | ||||||
| 		try { | 		PropertyValues pvs = new FilterConfigPropertyValues(filterConfig, this.requiredProperties); | ||||||
| 			PropertyValues pvs = new FilterConfigPropertyValues(filterConfig, this.requiredProperties); | 		if (!pvs.isEmpty()) { | ||||||
| 			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); | 			try { | ||||||
| 			ResourceLoader resourceLoader = new ServletContextResourceLoader(filterConfig.getServletContext()); | 				BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); | ||||||
| 			bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment)); | 				ResourceLoader resourceLoader = new ServletContextResourceLoader(filterConfig.getServletContext()); | ||||||
| 			initBeanWrapper(bw); | 				Environment env = this.environment; | ||||||
| 			bw.setPropertyValues(pvs, true); | 				if (env == null) { | ||||||
| 		} | 					env = new StandardServletEnvironment(); | ||||||
| 		catch (BeansException ex) { | 				} | ||||||
| 			String msg = "Failed to set bean properties on filter '" + | 				bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, env)); | ||||||
| 				filterConfig.getFilterName() + "': " + ex.getMessage(); | 				initBeanWrapper(bw); | ||||||
| 			logger.error(msg, ex); | 				bw.setPropertyValues(pvs, true); | ||||||
| 			throw new NestedServletException(msg, ex); | 			} | ||||||
|  | 			catch (BeansException ex) { | ||||||
|  | 				String msg = "Failed to set bean properties on filter '" + | ||||||
|  | 					filterConfig.getFilterName() + "': " + ex.getMessage(); | ||||||
|  | 				logger.error(msg, ex); | ||||||
|  | 				throw new NestedServletException(msg, ex); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Let subclasses do whatever initialization they like. | 		// Let subclasses do whatever initialization they like. | ||||||
|  | @ -214,6 +251,20 @@ public abstract class GenericFilterBean implements | ||||||
| 	protected void initBeanWrapper(BeanWrapper bw) throws BeansException { | 	protected void initBeanWrapper(BeanWrapper bw) throws BeansException { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Subclasses may override this to perform custom initialization. | ||||||
|  | 	 * All bean properties of this filter will have been set before this | ||||||
|  | 	 * method is invoked. | ||||||
|  | 	 * <p>Note: This method will be called from standard filter initialization | ||||||
|  | 	 * as well as filter bean initialization in a Spring application context. | ||||||
|  | 	 * Filter name and ServletContext will be available in both cases. | ||||||
|  | 	 * <p>This default implementation is empty. | ||||||
|  | 	 * @throws ServletException if subclass initialization fails | ||||||
|  | 	 * @see #getFilterName() | ||||||
|  | 	 * @see #getServletContext() | ||||||
|  | 	 */ | ||||||
|  | 	protected void initFilterBean() throws ServletException { | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Make the FilterConfig of this filter available, if any. | 	 * Make the FilterConfig of this filter available, if any. | ||||||
|  | @ -258,32 +309,6 @@ public abstract class GenericFilterBean implements | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	/** |  | ||||||
| 	 * Subclasses may override this to perform custom initialization. |  | ||||||
| 	 * All bean properties of this filter will have been set before this |  | ||||||
| 	 * method is invoked. |  | ||||||
| 	 * <p>Note: This method will be called from standard filter initialization |  | ||||||
| 	 * as well as filter bean initialization in a Spring application context. |  | ||||||
| 	 * Filter name and ServletContext will be available in both cases. |  | ||||||
| 	 * <p>This default implementation is empty. |  | ||||||
| 	 * @throws ServletException if subclass initialization fails |  | ||||||
| 	 * @see #getFilterName() |  | ||||||
| 	 * @see #getServletContext() |  | ||||||
| 	 */ |  | ||||||
| 	protected void initFilterBean() throws ServletException { |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/** |  | ||||||
| 	 * Subclasses may override this to perform custom filter shutdown. |  | ||||||
| 	 * <p>Note: This method will be called from standard filter destruction |  | ||||||
| 	 * as well as filter bean destruction in a Spring application context. |  | ||||||
| 	 * <p>This default implementation is empty. |  | ||||||
| 	 */ |  | ||||||
| 	@Override |  | ||||||
| 	public void destroy() { |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	/** | 	/** | ||||||
| 	 * PropertyValues implementation created from FilterConfig init parameters. | 	 * PropertyValues implementation created from FilterConfig init parameters. | ||||||
| 	 */ | 	 */ | ||||||
|  | @ -298,14 +323,14 @@ public abstract class GenericFilterBean implements | ||||||
| 		 * @throws ServletException if any required properties are missing | 		 * @throws ServletException if any required properties are missing | ||||||
| 		 */ | 		 */ | ||||||
| 		public FilterConfigPropertyValues(FilterConfig config, Set<String> requiredProperties) | 		public FilterConfigPropertyValues(FilterConfig config, Set<String> requiredProperties) | ||||||
| 			throws ServletException { | 				throws ServletException { | ||||||
| 
 | 
 | ||||||
| 			Set<String> missingProps = (requiredProperties != null && !requiredProperties.isEmpty()) ? | 			Set<String> missingProps = (!CollectionUtils.isEmpty(requiredProperties) ? | ||||||
| 					new HashSet<>(requiredProperties) : null; | 					new HashSet<>(requiredProperties) : null); | ||||||
| 
 | 
 | ||||||
| 			Enumeration<?> en = config.getInitParameterNames(); | 			Enumeration<String> paramNames = config.getInitParameterNames(); | ||||||
| 			while (en.hasMoreElements()) { | 			while (paramNames.hasMoreElements()) { | ||||||
| 				String property = (String) en.nextElement(); | 				String property = paramNames.nextElement(); | ||||||
| 				Object value = config.getInitParameter(property); | 				Object value = config.getInitParameter(property); | ||||||
| 				addPropertyValue(new PropertyValue(property, value)); | 				addPropertyValue(new PropertyValue(property, value)); | ||||||
| 				if (missingProps != null) { | 				if (missingProps != null) { | ||||||
|  | @ -314,11 +339,11 @@ public abstract class GenericFilterBean implements | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			// Fail if we are still missing properties. | 			// Fail if we are still missing properties. | ||||||
| 			if (missingProps != null && missingProps.size() > 0) { | 			if (!CollectionUtils.isEmpty(missingProps)) { | ||||||
| 				throw new ServletException( | 				throw new ServletException( | ||||||
| 					"Initialization from FilterConfig for filter '" + config.getFilterName() + | 						"Initialization from FilterConfig for filter '" + config.getFilterName() + | ||||||
| 					"' failed; the following required properties were missing: " + | 						"' failed; the following required properties were missing: " + | ||||||
| 					StringUtils.collectionToDelimitedString(missingProps, ", ")); | 						StringUtils.collectionToDelimitedString(missingProps, ", ")); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -84,14 +84,10 @@ public abstract class HttpServletBean extends HttpServlet implements Environment | ||||||
| 	/** Logger available to subclasses */ | 	/** Logger available to subclasses */ | ||||||
| 	protected final Log logger = LogFactory.getLog(getClass()); | 	protected final Log logger = LogFactory.getLog(getClass()); | ||||||
| 
 | 
 | ||||||
| 	/** |  | ||||||
| 	 * Set of required properties (Strings) that must be supplied as |  | ||||||
| 	 * config parameters to this servlet. |  | ||||||
| 	 */ |  | ||||||
| 	private final Set<String> requiredProperties = new HashSet<>(); |  | ||||||
| 
 |  | ||||||
| 	private ConfigurableEnvironment environment; | 	private ConfigurableEnvironment environment; | ||||||
| 
 | 
 | ||||||
|  | 	private final Set<String> requiredProperties = new HashSet<>(4); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Subclasses can invoke this method to specify that this property | 	 * Subclasses can invoke this method to specify that this property | ||||||
|  | @ -106,6 +102,41 @@ public abstract class HttpServletBean extends HttpServlet implements Environment | ||||||
| 		this.requiredProperties.add(property); | 		this.requiredProperties.add(property); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Set the {@code Environment} that this servlet runs in. | ||||||
|  | 	 * <p>Any environment set here overrides the {@link StandardServletEnvironment} | ||||||
|  | 	 * provided by default. | ||||||
|  | 	 * @throws IllegalArgumentException if environment is not assignable to | ||||||
|  | 	 * {@code ConfigurableEnvironment} | ||||||
|  | 	 */ | ||||||
|  | 	@Override | ||||||
|  | 	public void setEnvironment(Environment environment) { | ||||||
|  | 		Assert.isInstanceOf(ConfigurableEnvironment.class, environment, "ConfigurableEnvironment required"); | ||||||
|  | 		this.environment = (ConfigurableEnvironment) environment; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Return the {@link Environment} associated with this servlet. | ||||||
|  | 	 * <p>If none specified, a default environment will be initialized via | ||||||
|  | 	 * {@link #createEnvironment()}. | ||||||
|  | 	 */ | ||||||
|  | 	@Override | ||||||
|  | 	public ConfigurableEnvironment getEnvironment() { | ||||||
|  | 		if (this.environment == null) { | ||||||
|  | 			this.environment = createEnvironment(); | ||||||
|  | 		} | ||||||
|  | 		return this.environment; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Create and return a new {@link StandardServletEnvironment}. | ||||||
|  | 	 * <p>Subclasses may override this in order to configure the environment or | ||||||
|  | 	 * specialize the environment type returned. | ||||||
|  | 	 */ | ||||||
|  | 	protected ConfigurableEnvironment createEnvironment() { | ||||||
|  | 		return new StandardServletEnvironment(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Map config parameters onto bean properties of this servlet, and | 	 * Map config parameters onto bean properties of this servlet, and | ||||||
| 	 * invoke subclass initialization. | 	 * invoke subclass initialization. | ||||||
|  | @ -119,19 +150,21 @@ public abstract class HttpServletBean extends HttpServlet implements Environment | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Set bean properties from init parameters. | 		// Set bean properties from init parameters. | ||||||
| 		try { | 		PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties); | ||||||
| 			PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties); | 		if (!pvs.isEmpty()) { | ||||||
| 			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); | 			try { | ||||||
| 			ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext()); | 				BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); | ||||||
| 			bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment())); | 				ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext()); | ||||||
| 			initBeanWrapper(bw); | 				bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment())); | ||||||
| 			bw.setPropertyValues(pvs, true); | 				initBeanWrapper(bw); | ||||||
| 		} | 				bw.setPropertyValues(pvs, true); | ||||||
| 		catch (BeansException ex) { | 			} | ||||||
| 			if (logger.isErrorEnabled()) { | 			catch (BeansException ex) { | ||||||
| 				logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex); | 				if (logger.isErrorEnabled()) { | ||||||
|  | 					logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex); | ||||||
|  | 				} | ||||||
|  | 				throw ex; | ||||||
| 			} | 			} | ||||||
| 			throw ex; |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Let subclasses do whatever initialization they like. | 		// Let subclasses do whatever initialization they like. | ||||||
|  | @ -153,6 +186,15 @@ public abstract class HttpServletBean extends HttpServlet implements Environment | ||||||
| 	protected void initBeanWrapper(BeanWrapper bw) throws BeansException { | 	protected void initBeanWrapper(BeanWrapper bw) throws BeansException { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Subclasses may override this to perform custom initialization. | ||||||
|  | 	 * All bean properties of this servlet will have been set before this | ||||||
|  | 	 * method is invoked. | ||||||
|  | 	 * <p>This default implementation is empty. | ||||||
|  | 	 * @throws ServletException if subclass initialization fails | ||||||
|  | 	 */ | ||||||
|  | 	protected void initServletBean() throws ServletException { | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Overridden method that simply returns {@code null} when no | 	 * Overridden method that simply returns {@code null} when no | ||||||
|  | @ -175,49 +217,6 @@ public abstract class HttpServletBean extends HttpServlet implements Environment | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	/** |  | ||||||
| 	 * Subclasses may override this to perform custom initialization. |  | ||||||
| 	 * All bean properties of this servlet will have been set before this |  | ||||||
| 	 * method is invoked. |  | ||||||
| 	 * <p>This default implementation is empty. |  | ||||||
| 	 * @throws ServletException if subclass initialization fails |  | ||||||
| 	 */ |  | ||||||
| 	protected void initServletBean() throws ServletException { |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/** |  | ||||||
| 	 * {@inheritDoc} |  | ||||||
| 	 * @throws IllegalArgumentException if environment is not assignable to |  | ||||||
| 	 * {@code ConfigurableEnvironment}. |  | ||||||
| 	 */ |  | ||||||
| 	@Override |  | ||||||
| 	public void setEnvironment(Environment environment) { |  | ||||||
| 		Assert.isInstanceOf(ConfigurableEnvironment.class, environment, "ConfigurableEnvironment required"); |  | ||||||
| 		this.environment = (ConfigurableEnvironment) environment; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/** |  | ||||||
| 	 * {@inheritDoc} |  | ||||||
| 	 * <p>If {@code null}, a new environment will be initialized via |  | ||||||
| 	 * {@link #createEnvironment()}. |  | ||||||
| 	 */ |  | ||||||
| 	@Override |  | ||||||
| 	public ConfigurableEnvironment getEnvironment() { |  | ||||||
| 		if (this.environment == null) { |  | ||||||
| 			this.environment = this.createEnvironment(); |  | ||||||
| 		} |  | ||||||
| 		return this.environment; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/** |  | ||||||
| 	 * Create and return a new {@link StandardServletEnvironment}. Subclasses may override |  | ||||||
| 	 * in order to configure the environment or specialize the environment type returned. |  | ||||||
| 	 */ |  | ||||||
| 	protected ConfigurableEnvironment createEnvironment() { |  | ||||||
| 		return new StandardServletEnvironment(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	/** | 	/** | ||||||
| 	 * PropertyValues implementation created from ServletConfig init parameters. | 	 * PropertyValues implementation created from ServletConfig init parameters. | ||||||
| 	 */ | 	 */ | ||||||
|  | @ -231,9 +230,9 @@ public abstract class HttpServletBean extends HttpServlet implements Environment | ||||||
| 		 * @throws ServletException if any required properties are missing | 		 * @throws ServletException if any required properties are missing | ||||||
| 		 */ | 		 */ | ||||||
| 		public ServletConfigPropertyValues(ServletConfig config, Set<String> requiredProperties) | 		public ServletConfigPropertyValues(ServletConfig config, Set<String> requiredProperties) | ||||||
| 			throws ServletException { | 				throws ServletException { | ||||||
| 
 | 
 | ||||||
| 			Set<String> missingProps = (requiredProperties != null && !requiredProperties.isEmpty() ? | 			Set<String> missingProps = (!CollectionUtils.isEmpty(requiredProperties) ? | ||||||
| 					new HashSet<>(requiredProperties) : null); | 					new HashSet<>(requiredProperties) : null); | ||||||
| 
 | 
 | ||||||
| 			Enumeration<String> paramNames = config.getInitParameterNames(); | 			Enumeration<String> paramNames = config.getInitParameterNames(); | ||||||
|  | @ -249,9 +248,9 @@ public abstract class HttpServletBean extends HttpServlet implements Environment | ||||||
| 			// Fail if we are still missing properties. | 			// Fail if we are still missing properties. | ||||||
| 			if (!CollectionUtils.isEmpty(missingProps)) { | 			if (!CollectionUtils.isEmpty(missingProps)) { | ||||||
| 				throw new ServletException( | 				throw new ServletException( | ||||||
| 					"Initialization from ServletConfig for servlet '" + config.getServletName() + | 						"Initialization from ServletConfig for servlet '" + config.getServletName() + | ||||||
| 					"' failed; the following required properties were missing: " + | 						"' failed; the following required properties were missing: " + | ||||||
| 					StringUtils.collectionToDelimitedString(missingProps, ", ")); | 						StringUtils.collectionToDelimitedString(missingProps, ", ")); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue