Browse Source

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)
pull/931/head
Juergen Hoeller 10 years ago
parent
commit
4ff23f4708
  1. 55
      spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java
  2. 18
      spring-test/src/test/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilderTests.java

55
spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java

@ -1,5 +1,5 @@ @@ -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");
* you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@ import java.util.Map; @@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.BeanFactory;
@ -42,20 +43,22 @@ import org.springframework.core.env.Environment; @@ -42,20 +43,22 @@ import org.springframework.core.env.Environment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.WebApplicationContext;
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
* externally, there is no wiring, bean initialization, lifecycle events, as
* well as no pre-processing and post-processing hooks typically associated with
* beans managed by an {@link ApplicationContext}. Just a simple lookup into a
* <p>As registered object instances are instantiated and initialized externally,
* there is no wiring, bean initialization, lifecycle events, as well as no
* pre-processing and post-processing hooks typically associated with beans
* managed by an {@link ApplicationContext}. Just a simple lookup into a
* {@link StaticListableBeanFactory}.
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @since 3.2
*/
class StubWebApplicationContext implements WebApplicationContext {
@ -77,14 +80,12 @@ class StubWebApplicationContext implements WebApplicationContext { @@ -77,14 +80,12 @@ class StubWebApplicationContext implements WebApplicationContext {
private final ResourcePatternResolver resourcePatternResolver;
/**
* Class constructor.
*/
public StubWebApplicationContext(ServletContext servletContext) {
this.servletContext = servletContext;
this.resourcePatternResolver = new ServletContextResourcePatternResolver(servletContext);
}
/**
* Returns an instance that can initialize {@link ApplicationContextAware} beans.
*/
@ -98,6 +99,7 @@ class StubWebApplicationContext implements WebApplicationContext { @@ -98,6 +99,7 @@ class StubWebApplicationContext implements WebApplicationContext {
return this.servletContext;
}
//---------------------------------------------------------------------
// Implementation of ApplicationContext interface
//---------------------------------------------------------------------
@ -137,12 +139,16 @@ class StubWebApplicationContext implements WebApplicationContext { @@ -137,12 +139,16 @@ class StubWebApplicationContext implements WebApplicationContext {
}
public void addBeans(List<?> beans) {
if (beans == null) {
return;
}
for (Object bean : beans) {
String name = bean.getClass().getName() + "#" + ObjectUtils.getIdentityHexString(bean);
this.beanFactory.addBean(name, bean);
}
}
//---------------------------------------------------------------------
// Implementation of BeanFactory interface
//---------------------------------------------------------------------
@ -202,6 +208,7 @@ class StubWebApplicationContext implements WebApplicationContext { @@ -202,6 +208,7 @@ class StubWebApplicationContext implements WebApplicationContext {
return this.beanFactory.getAliases(name);
}
//---------------------------------------------------------------------
// Implementation of ListableBeanFactory interface
//---------------------------------------------------------------------
@ -262,6 +269,7 @@ class StubWebApplicationContext implements WebApplicationContext { @@ -262,6 +269,7 @@ class StubWebApplicationContext implements WebApplicationContext {
return this.beanFactory.findAnnotationOnBean(beanName, annotationType);
}
//---------------------------------------------------------------------
// Implementation of HierarchicalBeanFactory interface
//---------------------------------------------------------------------
@ -276,6 +284,7 @@ class StubWebApplicationContext implements WebApplicationContext { @@ -276,6 +284,7 @@ class StubWebApplicationContext implements WebApplicationContext {
return this.beanFactory.containsBean(name);
}
//---------------------------------------------------------------------
// Implementation of MessageSource interface
//---------------------------------------------------------------------
@ -295,13 +304,14 @@ class StubWebApplicationContext implements WebApplicationContext { @@ -295,13 +304,14 @@ class StubWebApplicationContext implements WebApplicationContext {
return this.messageSource.getMessage(resolvable, locale);
}
//---------------------------------------------------------------------
// Implementation of ResourceLoader interface
//---------------------------------------------------------------------
@Override
public ClassLoader getClassLoader() {
return null;
return ClassUtils.getDefaultClassLoader();
}
@Override
@ -309,6 +319,7 @@ class StubWebApplicationContext implements WebApplicationContext { @@ -309,6 +319,7 @@ class StubWebApplicationContext implements WebApplicationContext {
return this.resourcePatternResolver.getResource(location);
}
//---------------------------------------------------------------------
// Other
//---------------------------------------------------------------------
@ -340,65 +351,61 @@ class StubWebApplicationContext implements WebApplicationContext { @@ -340,65 +351,61 @@ class StubWebApplicationContext implements WebApplicationContext {
@Override
public <T> T createBean(Class<T> beanClass) {
throw new UnsupportedOperationException();
return BeanUtils.instantiate(beanClass);
}
@Override
@SuppressWarnings("rawtypes")
public Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck) {
throw new UnsupportedOperationException();
public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) {
return BeanUtils.instantiate(beanClass);
}
@Override
@SuppressWarnings("rawtypes")
public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) {
throw new UnsupportedOperationException();
public Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) {
return BeanUtils.instantiate(beanClass);
}
@Override
public void autowireBean(Object existingBean) throws BeansException {
throw new UnsupportedOperationException();
}
@Override
public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) {
throw new UnsupportedOperationException();
}
@Override
public Object configureBean(Object existingBean, String beanName) {
throw new UnsupportedOperationException();
return existingBean;
}
@Override
public Object resolveDependency(DependencyDescriptor descriptor, String beanName) {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException("Dependency resolution not supported");
}
@Override
public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) {
throw new UnsupportedOperationException();
throw new UnsupportedOperationException("Dependency resolution not supported");
}
@Override
public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException {
throw new UnsupportedOperationException();
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
throw new UnsupportedOperationException();
return existingBean;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
throw new UnsupportedOperationException();
return existingBean;
}
@Override
public void destroyBean(Object existingBean) {
throw new UnsupportedOperationException();
}
}

18
spring-test/src/test/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilderTests.java

@ -1,5 +1,5 @@ @@ -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");
* you may not use this file except in compliance with the License.
@ -23,8 +23,11 @@ import javax.servlet.ServletException; @@ -23,8 +23,11 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
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.springframework.http.converter.json.SpringHandlerInstantiator;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@ -46,7 +49,7 @@ import static org.junit.Assert.*; @@ -46,7 +49,7 @@ import static org.junit.Assert.*;
*/
public class StandaloneMockMvcBuilderTests {
@Test // SPR-10825
@Test // SPR-10825
public void placeHoldersInRequestMapping() throws Exception {
TestStandaloneMockMvcBuilder builder = new TestStandaloneMockMvcBuilder(new PlaceholderController());
@ -62,7 +65,7 @@ public class StandaloneMockMvcBuilderTests { @@ -62,7 +65,7 @@ public class StandaloneMockMvcBuilderTests {
assertEquals("handleWithPlaceholders", ((HandlerMethod) chain.getHandler()).getMethod().getName());
}
@Test // SPR-12553
@Test // SPR-12553
public void applicationContextAttribute() {
TestStandaloneMockMvcBuilder builder = new TestStandaloneMockMvcBuilder(new PlaceholderController());
builder.addPlaceHolderValue("sys.login.ajax", "/foo");
@ -96,6 +99,15 @@ public class StandaloneMockMvcBuilderTests { @@ -96,6 +99,15 @@ public class StandaloneMockMvcBuilderTests {
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
private static class PlaceholderController {

Loading…
Cancel
Save