polishing

This commit is contained in:
Juergen Hoeller 2011-07-18 21:37:24 +00:00
parent 236b0305e8
commit 94ac883eb1
2 changed files with 33 additions and 55 deletions

View File

@ -26,6 +26,7 @@ import java.util.Stack;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.BeanDefinitionStoreException;
@ -95,6 +96,8 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
private ProblemReporter problemReporter = new FailFastProblemReporter(); private ProblemReporter problemReporter = new FailFastProblemReporter();
private Environment environment;
private ResourceLoader resourceLoader = new DefaultResourceLoader(); private ResourceLoader resourceLoader = new DefaultResourceLoader();
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
@ -107,8 +110,6 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
private final Set<Integer> factoriesPostProcessed = new HashSet<Integer>(); private final Set<Integer> factoriesPostProcessed = new HashSet<Integer>();
private Environment environment;
private ConfigurationClassBeanDefinitionReader reader; private ConfigurationClassBeanDefinitionReader reader;
@ -141,6 +142,11 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
this.setMetadataReaderFactoryCalled = true; this.setMetadataReaderFactoryCalled = true;
} }
public void setEnvironment(Environment environment) {
Assert.notNull(environment, "Environment must not be null");
this.environment = environment;
}
public void setResourceLoader(ResourceLoader resourceLoader) { public void setResourceLoader(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null"); Assert.notNull(resourceLoader, "ResourceLoader must not be null");
this.resourceLoader = resourceLoader; this.resourceLoader = resourceLoader;
@ -153,27 +159,22 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
} }
} }
public void setEnvironment(Environment environment) {
Assert.notNull(environment, "Environment must not be null");
this.environment = environment;
}
/** /**
* Derive further bean definitions from the configuration classes in the registry. * Derive further bean definitions from the configuration classes in the registry.
*/ */
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
BeanDefinitionReaderUtils.registerWithGeneratedName(new RootBeanDefinition(ImportAwareBeanPostProcessor.class), registry); BeanDefinitionReaderUtils.registerWithGeneratedName(new RootBeanDefinition(ImportAwareBeanPostProcessor.class), registry);
int registryID = System.identityHashCode(registry); int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryID)) { if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException( throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called for this post-processor against " + registry); "postProcessBeanDefinitionRegistry already called for this post-processor against " + registry);
} }
if (this.factoriesPostProcessed.contains(registryID)) { if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException( throw new IllegalStateException(
"postProcessBeanFactory already called for this post-processor against " + registry); "postProcessBeanFactory already called for this post-processor against " + registry);
} }
this.registriesPostProcessed.add(registryID); this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry); processConfigBeanDefinitions(registry);
} }
@ -182,13 +183,13 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
* by replacing them with CGLIB-enhanced subclasses. * by replacing them with CGLIB-enhanced subclasses.
*/ */
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryID = System.identityHashCode(beanFactory); int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryID)) { if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException( throw new IllegalStateException(
"postProcessBeanFactory already called for this post-processor against " + beanFactory); "postProcessBeanFactory already called for this post-processor against " + beanFactory);
} }
this.factoriesPostProcessed.add(factoryID); this.factoriesPostProcessed.add((factoryId));
if (!this.registriesPostProcessed.contains(factoryID)) { if (!this.registriesPostProcessed.contains((factoryId))) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported... // BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then. // Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
@ -327,9 +328,11 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
String importingClass = importRegistry.getImportingClassFor(bean.getClass().getSuperclass().getName()); String importingClass = importRegistry.getImportingClassFor(bean.getClass().getSuperclass().getName());
if (importingClass != null) { if (importingClass != null) {
try { try {
AnnotationMetadata metadata = new SimpleMetadataReaderFactory().getMetadataReader(importingClass).getAnnotationMetadata(); AnnotationMetadata metadata =
new SimpleMetadataReaderFactory().getMetadataReader(importingClass).getAnnotationMetadata();
((ImportAware) bean).setImportMetadata(metadata); ((ImportAware) bean).setImportMetadata(metadata);
} catch (IOException ex) { }
catch (IOException ex) {
// should never occur -> at this point we know the class is present anyway // should never occur -> at this point we know the class is present anyway
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
@ -349,4 +352,5 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
return Ordered.HIGHEST_PRECEDENCE; return Ordered.HIGHEST_PRECEDENCE;
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2011 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.
@ -34,6 +34,7 @@ import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError; import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement; import org.junit.runners.model.Statement;
import org.springframework.test.annotation.ExpectedException; import org.springframework.test.annotation.ExpectedException;
import org.springframework.test.annotation.ProfileValueUtils; import org.springframework.test.annotation.ProfileValueUtils;
import org.springframework.test.annotation.Repeat; import org.springframework.test.annotation.Repeat;
@ -96,7 +97,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* Constructs a new <code>SpringJUnit4ClassRunner</code> and initializes a * Constructs a new <code>SpringJUnit4ClassRunner</code> and initializes a
* {@link TestContextManager} to provide Spring testing functionality to * {@link TestContextManager} to provide Spring testing functionality to
* standard JUnit tests. * standard JUnit tests.
*
* @param clazz the test class to be run * @param clazz the test class to be run
* @see #createTestContextManager(Class) * @see #createTestContextManager(Class)
*/ */
@ -112,7 +112,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* Creates a new {@link TestContextManager} for the supplied test class and * Creates a new {@link TestContextManager} for the supplied test class and
* the configured <em>default <code>ContextLoader</code> class name</em>. * the configured <em>default <code>ContextLoader</code> class name</em>.
* Can be overridden by subclasses. * Can be overridden by subclasses.
*
* @param clazz the test class to be managed * @param clazz the test class to be managed
* @see #getDefaultContextLoaderClassName(Class) * @see #getDefaultContextLoaderClassName(Class)
*/ */
@ -132,12 +131,9 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* the supplied test class. The named class will be used if the test class * the supplied test class. The named class will be used if the test class
* does not explicitly declare a <code>ContextLoader</code> class via the * does not explicitly declare a <code>ContextLoader</code> class via the
* <code>&#064;ContextConfiguration</code> annotation. * <code>&#064;ContextConfiguration</code> annotation.
* <p> * <p>The default implementation returns <code>null</code>, thus implying use
* The default implementation returns <code>null</code>, thus implying use
* of the <em>standard</em> default <code>ContextLoader</code> class name. * of the <em>standard</em> default <code>ContextLoader</code> class name.
* Can be overridden by subclasses. * Can be overridden by subclasses.
* </p>
*
* @param clazz the test class * @param clazz the test class
* @return <code>null</code> * @return <code>null</code>
*/ */
@ -149,7 +145,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* Returns a description suitable for an ignored test class if the test is * Returns a description suitable for an ignored test class if the test is
* disabled via <code>&#064;IfProfileValue</code> at the class-level, and * disabled via <code>&#064;IfProfileValue</code> at the class-level, and
* otherwise delegates to the parent implementation. * otherwise delegates to the parent implementation.
*
* @see ProfileValueUtils#isTestEnabledInThisEnvironment(Class) * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Class)
*/ */
@Override @Override
@ -166,7 +161,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* from running altogether, even skipping the execution of * from running altogether, even skipping the execution of
* <code>prepareTestInstance()</code> <code>TestExecutionListener</code> * <code>prepareTestInstance()</code> <code>TestExecutionListener</code>
* methods. * methods.
*
* @see ProfileValueUtils#isTestEnabledInThisEnvironment(Class) * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Class)
* @see org.springframework.test.annotation.IfProfileValue * @see org.springframework.test.annotation.IfProfileValue
* @see org.springframework.test.context.TestExecutionListener * @see org.springframework.test.context.TestExecutionListener
@ -185,7 +179,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* {@link RunBeforeTestClassCallbacks} statement, thus preserving the * {@link RunBeforeTestClassCallbacks} statement, thus preserving the
* default functionality but adding support for the Spring TestContext * default functionality but adding support for the Spring TestContext
* Framework. * Framework.
*
* @see RunBeforeTestClassCallbacks * @see RunBeforeTestClassCallbacks
*/ */
@Override @Override
@ -198,7 +191,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* Wraps the {@link Statement} returned by the parent implementation with a * Wraps the {@link Statement} returned by the parent implementation with a
* {@link RunAfterTestClassCallbacks} statement, thus preserving the default * {@link RunAfterTestClassCallbacks} statement, thus preserving the default
* functionality but adding support for the Spring TestContext Framework. * functionality but adding support for the Spring TestContext Framework.
*
* @see RunAfterTestClassCallbacks * @see RunAfterTestClassCallbacks
*/ */
@Override @Override
@ -211,7 +203,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* Delegates to the parent implementation for creating the test instance and * Delegates to the parent implementation for creating the test instance and
* then allows the {@link #getTestContextManager() TestContextManager} to * then allows the {@link #getTestContextManager() TestContextManager} to
* prepare the test instance before returning it. * prepare the test instance before returning it.
*
* @see TestContextManager#prepareTestInstance(Object) * @see TestContextManager#prepareTestInstance(Object)
*/ */
@Override @Override
@ -267,8 +258,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* Augments the default JUnit behavior * Augments the default JUnit behavior
* {@link #withPotentialRepeat(FrameworkMethod, Object, Statement) with * {@link #withPotentialRepeat(FrameworkMethod, Object, Statement) with
* potential repeats} of the entire execution chain. * potential repeats} of the entire execution chain.
* <p> * <p>Furthermore, support for timeouts has been moved down the execution chain
* Furthermore, support for timeouts has been moved down the execution chain
* in order to include execution of {@link org.junit.Before &#064;Before} * in order to include execution of {@link org.junit.Before &#064;Before}
* and {@link org.junit.After &#064;After} methods within the timed * and {@link org.junit.After &#064;After} methods within the timed
* execution. Note that this differs from the default JUnit behavior of * execution. Note that this differs from the default JUnit behavior of
@ -281,8 +271,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* timeouts still differ from Spring-specific timeouts in that the former * timeouts still differ from Spring-specific timeouts in that the former
* execute in a separate thread while the latter simply execute in the main * execute in a separate thread while the latter simply execute in the main
* thread (like regular tests). * thread (like regular tests).
* </p>
*
* @see #possiblyExpectingExceptions(FrameworkMethod, Object, Statement) * @see #possiblyExpectingExceptions(FrameworkMethod, Object, Statement)
* @see #withBefores(FrameworkMethod, Object, Statement) * @see #withBefores(FrameworkMethod, Object, Statement)
* @see #withAfters(FrameworkMethod, Object, Statement) * @see #withAfters(FrameworkMethod, Object, Statement)
@ -291,19 +279,17 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
*/ */
@Override @Override
protected Statement methodBlock(FrameworkMethod frameworkMethod) { protected Statement methodBlock(FrameworkMethod frameworkMethod) {
Object testInstance; Object testInstance;
try { try {
testInstance = new ReflectiveCallable() { testInstance = new ReflectiveCallable() {
@Override @Override
protected Object runReflectiveCall() throws Throwable { protected Object runReflectiveCall() throws Throwable {
return createTest(); return createTest();
} }
}.run(); }.run();
} }
catch (Throwable e) { catch (Throwable ex) {
return new Fail(e); return new Fail(ex);
} }
Statement statement = methodInvoker(frameworkMethod, testInstance); Statement statement = methodInvoker(frameworkMethod, testInstance);
@ -339,7 +325,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* Returns <code>true</code> if {@link Ignore &#064;Ignore} is present for * Returns <code>true</code> if {@link Ignore &#064;Ignore} is present for
* the supplied {@link FrameworkMethod test method} or if the test method is * the supplied {@link FrameworkMethod test method} or if the test method is
* disabled via <code>&#064;IfProfileValue</code>. * disabled via <code>&#064;IfProfileValue</code>.
*
* @see ProfileValueUtils#isTestEnabledInThisEnvironment(Method, Class) * @see ProfileValueUtils#isTestEnabledInThisEnvironment(Method, Class)
*/ */
protected boolean isTestMethodIgnored(FrameworkMethod frameworkMethod) { protected boolean isTestMethodIgnored(FrameworkMethod frameworkMethod) {
@ -363,19 +348,15 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
/** /**
* Get the <code>exception</code> that the supplied {@link FrameworkMethod * Get the <code>exception</code> that the supplied {@link FrameworkMethod
* test method} is expected to throw. * test method} is expected to throw.
* <p> * <p>Supports both Spring's {@link ExpectedException @ExpectedException(...)}
* Supports both Spring's {@link ExpectedException @ExpectedException(...)}
* and JUnit's {@link Test#expected() @Test(expected=...)} annotations, but * and JUnit's {@link Test#expected() @Test(expected=...)} annotations, but
* not both simultaneously. * not both simultaneously.
* </p> * @return the expected exception, or <code>null</code> if none was specified
*
* @return the expected exception, or <code>null</code> if none was
* specified
*/ */
protected Class<? extends Throwable> getExpectedException(FrameworkMethod frameworkMethod) { protected Class<? extends Throwable> getExpectedException(FrameworkMethod frameworkMethod) {
Test testAnnotation = frameworkMethod.getAnnotation(Test.class); Test testAnnotation = frameworkMethod.getAnnotation(Test.class);
Class<? extends Throwable> junitExpectedException = testAnnotation != null Class<? extends Throwable> junitExpectedException = (testAnnotation != null &&
&& testAnnotation.expected() != Test.None.class ? testAnnotation.expected() : null; testAnnotation.expected() != Test.None.class ? testAnnotation.expected() : null);
ExpectedException expectedExAnn = frameworkMethod.getAnnotation(ExpectedException.class); ExpectedException expectedExAnn = frameworkMethod.getAnnotation(ExpectedException.class);
Class<? extends Throwable> springExpectedException = (expectedExAnn != null ? expectedExAnn.value() : null); Class<? extends Throwable> springExpectedException = (expectedExAnn != null ? expectedExAnn.value() : null);
@ -399,7 +380,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* simultaneously. Returns either a {@link SpringFailOnTimeout}, a * simultaneously. Returns either a {@link SpringFailOnTimeout}, a
* {@link FailOnTimeout}, or the unmodified, supplied {@link Statement} as * {@link FailOnTimeout}, or the unmodified, supplied {@link Statement} as
* appropriate. * appropriate.
*
* @see #getSpringTimeout(FrameworkMethod) * @see #getSpringTimeout(FrameworkMethod)
* @see #getJUnitTimeout(FrameworkMethod) * @see #getJUnitTimeout(FrameworkMethod)
*/ */
@ -431,9 +411,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
/** /**
* Retrieves the configured JUnit <code>timeout</code> from the {@link Test * Retrieves the configured JUnit <code>timeout</code> from the {@link Test
* &#064;Test} annotation on the supplied {@link FrameworkMethod test * &#064;Test} annotation on the supplied {@link FrameworkMethod test method}.
* method}.
*
* @return the timeout, or <code>0</code> if none was specified. * @return the timeout, or <code>0</code> if none was specified.
*/ */
protected long getJUnitTimeout(FrameworkMethod frameworkMethod) { protected long getJUnitTimeout(FrameworkMethod frameworkMethod) {
@ -445,7 +423,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* Retrieves the configured Spring-specific <code>timeout</code> from the * Retrieves the configured Spring-specific <code>timeout</code> from the
* {@link Timed &#064;Timed} annotation on the supplied * {@link Timed &#064;Timed} annotation on the supplied
* {@link FrameworkMethod test method}. * {@link FrameworkMethod test method}.
*
* @return the timeout, or <code>0</code> if none was specified. * @return the timeout, or <code>0</code> if none was specified.
*/ */
protected long getSpringTimeout(FrameworkMethod frameworkMethod) { protected long getSpringTimeout(FrameworkMethod frameworkMethod) {
@ -458,7 +435,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* {@link RunBeforeTestMethodCallbacks} statement, thus preserving the * {@link RunBeforeTestMethodCallbacks} statement, thus preserving the
* default functionality but adding support for the Spring TestContext * default functionality but adding support for the Spring TestContext
* Framework. * Framework.
*
* @see RunBeforeTestMethodCallbacks * @see RunBeforeTestMethodCallbacks
*/ */
@Override @Override
@ -474,7 +450,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* {@link RunAfterTestMethodCallbacks} statement, thus preserving the * {@link RunAfterTestMethodCallbacks} statement, thus preserving the
* default functionality but adding support for the Spring TestContext * default functionality but adding support for the Spring TestContext
* Framework. * Framework.
*
* @see RunAfterTestMethodCallbacks * @see RunAfterTestMethodCallbacks
*/ */
@Override @Override
@ -489,7 +464,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* Supports Spring's {@link Repeat &#064;Repeat} annotation by returning a * Supports Spring's {@link Repeat &#064;Repeat} annotation by returning a
* {@link SpringRepeat} statement initialized with the configured repeat * {@link SpringRepeat} statement initialized with the configured repeat
* count or <code>1</code> if no repeat count is configured. * count or <code>1</code> if no repeat count is configured.
*
* @see SpringRepeat * @see SpringRepeat
*/ */
protected Statement withPotentialRepeat(FrameworkMethod frameworkMethod, Object testInstance, Statement next) { protected Statement withPotentialRepeat(FrameworkMethod frameworkMethod, Object testInstance, Statement next) {