StubWebApplicationContext supports AutowireCapableBeanFactory operations (as far as possible)
This is generally worthwhile but in particular fixes a regression with our Jackson SpringHandlerInstantiator in standalone MVC tests.
Issue: SPR-13375
(cherry picked from commit 7d30017)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 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.
|
||||||
@@ -24,6 +24,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.TypeConverter;
|
import org.springframework.beans.TypeConverter;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
@@ -42,20 +43,22 @@ import org.springframework.core.env.Environment;
|
|||||||
import org.springframework.core.env.StandardEnvironment;
|
import org.springframework.core.env.StandardEnvironment;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
import org.springframework.web.context.support.ServletContextResourcePatternResolver;
|
import org.springframework.web.context.support.ServletContextResourcePatternResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mock WebApplicationContext that accepts registrations of object instances.
|
* A stub WebApplicationContext that accepts registrations of object instances.
|
||||||
*
|
*
|
||||||
* <p>As registered object instances are instantiated and initialized
|
* <p>As registered object instances are instantiated and initialized externally,
|
||||||
* externally, there is no wiring, bean initialization, lifecycle events, as
|
* there is no wiring, bean initialization, lifecycle events, as well as no
|
||||||
* well as no pre-processing and post-processing hooks typically associated with
|
* pre-processing and post-processing hooks typically associated with beans
|
||||||
* beans managed by an {@link ApplicationContext}. Just a simple lookup into a
|
* managed by an {@link ApplicationContext}. Just a simple lookup into a
|
||||||
* {@link StaticListableBeanFactory}.
|
* {@link StaticListableBeanFactory}.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
class StubWebApplicationContext implements WebApplicationContext {
|
class StubWebApplicationContext implements WebApplicationContext {
|
||||||
@@ -77,14 +80,12 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||||||
private final ResourcePatternResolver resourcePatternResolver;
|
private final ResourcePatternResolver resourcePatternResolver;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class constructor.
|
|
||||||
*/
|
|
||||||
public StubWebApplicationContext(ServletContext servletContext) {
|
public StubWebApplicationContext(ServletContext servletContext) {
|
||||||
this.servletContext = servletContext;
|
this.servletContext = servletContext;
|
||||||
this.resourcePatternResolver = new ServletContextResourcePatternResolver(servletContext);
|
this.resourcePatternResolver = new ServletContextResourcePatternResolver(servletContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an instance that can initialize {@link ApplicationContextAware} beans.
|
* Returns an instance that can initialize {@link ApplicationContextAware} beans.
|
||||||
*/
|
*/
|
||||||
@@ -98,6 +99,7 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||||||
return this.servletContext;
|
return this.servletContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Implementation of ApplicationContext interface
|
// Implementation of ApplicationContext interface
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
@@ -137,12 +139,16 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addBeans(List<?> beans) {
|
public void addBeans(List<?> beans) {
|
||||||
|
if (beans == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (Object bean : beans) {
|
for (Object bean : beans) {
|
||||||
String name = bean.getClass().getName() + "#" + ObjectUtils.getIdentityHexString(bean);
|
String name = bean.getClass().getName() + "#" + ObjectUtils.getIdentityHexString(bean);
|
||||||
this.beanFactory.addBean(name, bean);
|
this.beanFactory.addBean(name, bean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Implementation of BeanFactory interface
|
// Implementation of BeanFactory interface
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
@@ -202,6 +208,7 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||||||
return this.beanFactory.getAliases(name);
|
return this.beanFactory.getAliases(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Implementation of ListableBeanFactory interface
|
// Implementation of ListableBeanFactory interface
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
@@ -262,6 +269,7 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||||||
return this.beanFactory.findAnnotationOnBean(beanName, annotationType);
|
return this.beanFactory.findAnnotationOnBean(beanName, annotationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Implementation of HierarchicalBeanFactory interface
|
// Implementation of HierarchicalBeanFactory interface
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
@@ -276,6 +284,7 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||||||
return this.beanFactory.containsBean(name);
|
return this.beanFactory.containsBean(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Implementation of MessageSource interface
|
// Implementation of MessageSource interface
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
@@ -295,13 +304,14 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||||||
return this.messageSource.getMessage(resolvable, locale);
|
return this.messageSource.getMessage(resolvable, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Implementation of ResourceLoader interface
|
// Implementation of ResourceLoader interface
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return null;
|
return ClassUtils.getDefaultClassLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -309,6 +319,7 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||||||
return this.resourcePatternResolver.getResource(location);
|
return this.resourcePatternResolver.getResource(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Other
|
// Other
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
@@ -340,65 +351,61 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T createBean(Class<T> beanClass) {
|
public <T> T createBean(Class<T> beanClass) {
|
||||||
throw new UnsupportedOperationException();
|
return BeanUtils.instantiate(beanClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck) {
|
public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) {
|
||||||
throw new UnsupportedOperationException();
|
return BeanUtils.instantiate(beanClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) {
|
public Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) {
|
||||||
throw new UnsupportedOperationException();
|
return BeanUtils.instantiate(beanClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void autowireBean(Object existingBean) throws BeansException {
|
public void autowireBean(Object existingBean) throws BeansException {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) {
|
public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object configureBean(Object existingBean, String beanName) {
|
public Object configureBean(Object existingBean, String beanName) {
|
||||||
throw new UnsupportedOperationException();
|
return existingBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object resolveDependency(DependencyDescriptor descriptor, String beanName) {
|
public Object resolveDependency(DependencyDescriptor descriptor, String beanName) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException("Dependency resolution not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
|
public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
|
||||||
Set<String> autowiredBeanNames, TypeConverter typeConverter) {
|
Set<String> autowiredBeanNames, TypeConverter typeConverter) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException("Dependency resolution not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException {
|
public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
|
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
|
||||||
throw new UnsupportedOperationException();
|
return existingBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
|
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
|
||||||
throw new UnsupportedOperationException();
|
return existingBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroyBean(Object existingBean) {
|
public void destroyBean(Object existingBean) {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 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.
|
||||||
@@ -23,8 +23,11 @@ import javax.servlet.ServletException;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.ser.impl.UnknownSerializer;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.http.converter.json.SpringHandlerInstantiator;
|
||||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -46,7 +49,7 @@ import static org.junit.Assert.*;
|
|||||||
*/
|
*/
|
||||||
public class StandaloneMockMvcBuilderTests {
|
public class StandaloneMockMvcBuilderTests {
|
||||||
|
|
||||||
@Test // SPR-10825
|
@Test // SPR-10825
|
||||||
public void placeHoldersInRequestMapping() throws Exception {
|
public void placeHoldersInRequestMapping() throws Exception {
|
||||||
|
|
||||||
TestStandaloneMockMvcBuilder builder = new TestStandaloneMockMvcBuilder(new PlaceholderController());
|
TestStandaloneMockMvcBuilder builder = new TestStandaloneMockMvcBuilder(new PlaceholderController());
|
||||||
@@ -62,7 +65,7 @@ public class StandaloneMockMvcBuilderTests {
|
|||||||
assertEquals("handleWithPlaceholders", ((HandlerMethod) chain.getHandler()).getMethod().getName());
|
assertEquals("handleWithPlaceholders", ((HandlerMethod) chain.getHandler()).getMethod().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // SPR-12553
|
@Test // SPR-12553
|
||||||
public void applicationContextAttribute() {
|
public void applicationContextAttribute() {
|
||||||
TestStandaloneMockMvcBuilder builder = new TestStandaloneMockMvcBuilder(new PlaceholderController());
|
TestStandaloneMockMvcBuilder builder = new TestStandaloneMockMvcBuilder(new PlaceholderController());
|
||||||
builder.addPlaceHolderValue("sys.login.ajax", "/foo");
|
builder.addPlaceHolderValue("sys.login.ajax", "/foo");
|
||||||
@@ -96,6 +99,15 @@ public class StandaloneMockMvcBuilderTests {
|
|||||||
builder.addFilter(new ContinueFilter(), (String) null);
|
builder.addFilter(new ContinueFilter(), (String) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // SPR-13375
|
||||||
|
public void springHandlerInstantiator() {
|
||||||
|
TestStandaloneMockMvcBuilder builder = new TestStandaloneMockMvcBuilder(new PersonController());
|
||||||
|
builder.build();
|
||||||
|
SpringHandlerInstantiator instantiator = new SpringHandlerInstantiator(builder.wac.getAutowireCapableBeanFactory());
|
||||||
|
JsonSerializer serializer = instantiator.serializerInstance(null, null, UnknownSerializer.class);
|
||||||
|
assertNotNull(serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
private static class PlaceholderController {
|
private static class PlaceholderController {
|
||||||
|
|||||||
Reference in New Issue
Block a user