Browse Source

Polishing

pull/545/head
Juergen Hoeller 12 years ago
parent
commit
a5606a6c46
  1. 12
      spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java
  2. 8
      spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
  3. 130
      spring-context/src/test/java/org/springframework/context/annotation/configuration/Spr10744Tests.java
  4. 43
      spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
  5. 18
      spring-core/src/main/java/org/springframework/core/env/EnumerablePropertySource.java
  6. 91
      spring-core/src/main/java/org/springframework/core/env/PropertySource.java
  7. 17
      spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java
  8. 58
      spring-test/src/main/java/org/springframework/test/context/TestContextManager.java
  9. 31
      spring-web/src/test/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContextTests.java

12
spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java

@ -220,8 +220,8 @@ class TypeConverterDelegate { @@ -220,8 +220,8 @@ class TypeConverterDelegate {
else if (convertedValue instanceof String && !requiredType.isInstance(convertedValue)) {
if (firstAttemptEx == null && !requiredType.isInterface() && !requiredType.isEnum()) {
try {
Constructor strCtor = requiredType.getConstructor(String.class);
return (T) BeanUtils.instantiateClass(strCtor, convertedValue);
Constructor<T> strCtor = requiredType.getConstructor(String.class);
return BeanUtils.instantiateClass(strCtor, convertedValue);
}
catch (NoSuchMethodException ex) {
// proceed with field lookup
@ -331,7 +331,7 @@ class TypeConverterDelegate { @@ -331,7 +331,7 @@ class TypeConverterDelegate {
* @param requiredType the type to find an editor for
* @return the corresponding editor, or {@code null} if none
*/
private PropertyEditor findDefaultEditor(Class requiredType) {
private PropertyEditor findDefaultEditor(Class<?> requiredType) {
PropertyEditor editor = null;
if (requiredType != null) {
// No custom editor -> check BeanWrapperImpl's default editors.
@ -496,7 +496,7 @@ class TypeConverterDelegate { @@ -496,7 +496,7 @@ class TypeConverterDelegate {
@SuppressWarnings("unchecked")
private Collection convertToTypedCollection(
Collection original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
Collection original, String propertyName, Class<?> requiredType, TypeDescriptor typeDescriptor) {
if (!Collection.class.isAssignableFrom(requiredType)) {
return original;
@ -578,7 +578,7 @@ class TypeConverterDelegate { @@ -578,7 +578,7 @@ class TypeConverterDelegate {
@SuppressWarnings("unchecked")
private Map convertToTypedMap(
Map original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
Map original, String propertyName, Class<?> requiredType, TypeDescriptor typeDescriptor) {
if (!Map.class.isAssignableFrom(requiredType)) {
return original;
@ -674,7 +674,7 @@ class TypeConverterDelegate { @@ -674,7 +674,7 @@ class TypeConverterDelegate {
null);
}
private boolean canCreateCopy(Class requiredType) {
private boolean canCreateCopy(Class<?> requiredType) {
return (!requiredType.isInterface() && !Modifier.isAbstract(requiredType.getModifiers()) &&
Modifier.isPublic(requiredType.getModifiers()) && ClassUtils.hasConstructor(requiredType));
}

8
spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java

@ -65,7 +65,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -65,7 +65,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
private static final Log logger = LogFactory.getLog(DisposableBeanAdapter.class);
private static Class closeableInterface;
private static Class<?> closeableInterface;
static {
try {
@ -86,14 +86,14 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -86,14 +86,14 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
private final boolean nonPublicAccessAllowed;
private final AccessControlContext acc;
private String destroyMethodName;
private transient Method destroyMethod;
private List<DestructionAwareBeanPostProcessor> beanPostProcessors;
private final AccessControlContext acc;
/**
* Create a new DisposableBeanAdapter for the given bean.
@ -150,9 +150,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { @@ -150,9 +150,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
this.beanName = beanName;
this.invokeDisposableBean = invokeDisposableBean;
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
this.acc = null;
this.destroyMethodName = destroyMethodName;
this.beanPostProcessors = postProcessors;
this.acc = null;
}

130
spring-context/src/test/java/org/springframework/context/annotation/configuration/Spr10744Tests.java

@ -0,0 +1,130 @@ @@ -0,0 +1,130 @@
/*
* Copyright 2002-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.annotation.configuration;
import org.junit.Test;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
/**
* @author Phillip Webb
*/
public class Spr10744Tests {
private static int createCount = 0;
private static int scopeCount = 0;
@Test
public void testSpr10744() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getBeanFactory().registerScope("myTestScope", new MyTestScope());
context.register(MyTestConfiguration.class);
context.refresh();
Foo bean1 = context.getBean("foo", Foo.class);
Foo bean2 = context.getBean("foo", Foo.class);
assertThat(bean1, sameInstance(bean2));
// Should have created a single instance for the proxy
assertThat(createCount, equalTo(1));
assertThat(scopeCount, equalTo(0));
// Proxy mode should create new scoped object on each method call
bean1.getMessage();
assertThat(createCount, equalTo(2));
assertThat(scopeCount, equalTo(1));
bean1.getMessage();
assertThat(createCount, equalTo(3));
assertThat(scopeCount, equalTo(2));
context.close();
}
private static class MyTestScope implements org.springframework.beans.factory.config.Scope {
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
scopeCount++;
return objectFactory.getObject();
}
@Override
public Object remove(String name) {
return null;
}
@Override
public void registerDestructionCallback(String name, Runnable callback) {
}
@Override
public Object resolveContextualObject(String key) {
return null;
}
@Override
public String getConversationId() {
return null;
}
}
static class Foo {
public Foo() {
createCount++;
}
public String getMessage() {
return "Hello";
}
}
@Configuration
static class MyConfiguration {
@Bean
public Foo foo() {
return new Foo();
}
}
@Configuration
static class MyTestConfiguration extends MyConfiguration {
@Bean
@Scope(value = "myTestScope", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Override
public Foo foo() {
return new Foo();
}
}
}

43
spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.
@ -25,6 +25,7 @@ import java.util.WeakHashMap; @@ -25,6 +25,7 @@ import java.util.WeakHashMap;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* General utility methods for working with annotations, handling bridge methods (which the compiler
@ -60,8 +61,8 @@ public abstract class AnnotationUtils { @@ -60,8 +61,8 @@ public abstract class AnnotationUtils {
* Method, Constructor or Field. Meta-annotations will be searched if the annotation
* is not declared locally on the supplied element.
* @param ae the Method, Constructor or Field from which to get the annotation
* @param annotationType the annotation class to look for, both locally and as a meta-annotation
* @return the matching annotation or {@code null} if not found
* @param annotationType the annotation type to look for, both locally and as a meta-annotation
* @return the matching annotation, or {@code null} if none found
* @since 3.1
*/
public static <T extends Annotation> T getAnnotation(AnnotatedElement ae, Class<T> annotationType) {
@ -92,7 +93,7 @@ public abstract class AnnotationUtils { @@ -92,7 +93,7 @@ public abstract class AnnotationUtils {
* Get a single {@link Annotation} of {@code annotationType} from the supplied {@link Method}.
* <p>Correctly handles bridge {@link Method Methods} generated by the compiler.
* @param method the method to look for annotations on
* @param annotationType the annotation class to look for
* @param annotationType the annotation type to look for
* @return the annotations found
* @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method)
*/
@ -115,8 +116,8 @@ public abstract class AnnotationUtils { @@ -115,8 +116,8 @@ public abstract class AnnotationUtils {
* traversing its super methods if no annotation can be found on the given method itself.
* <p>Annotations on methods are not inherited by default, so we need to handle this explicitly.
* @param method the method to look for annotations on
* @param annotationType the annotation class to look for
* @return the annotation found, or {@code null} if none found
* @param annotationType the annotation type to look for
* @return the annotation found, or {@code null} if none
*/
public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) {
A annotation = getAnnotation(method, annotationType);
@ -192,7 +193,7 @@ public abstract class AnnotationUtils { @@ -192,7 +193,7 @@ public abstract class AnnotationUtils {
* with the interfaces that the superclass declares. Recursing up through the entire superclass
* hierarchy if no match is found.
* @param clazz the class to look for annotations on
* @param annotationType the annotation class to look for
* @param annotationType the annotation type to look for
* @return the annotation found, or {@code null} if none found
*/
public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType) {
@ -215,11 +216,11 @@ public abstract class AnnotationUtils { @@ -215,11 +216,11 @@ public abstract class AnnotationUtils {
}
}
}
Class<?> superClass = clazz.getSuperclass();
if (superClass == null || superClass.equals(Object.class)) {
Class<?> superclass = clazz.getSuperclass();
if (superclass == null || superclass.equals(Object.class)) {
return null;
}
return findAnnotation(superClass, annotationType);
return findAnnotation(superclass, annotationType);
}
/**
@ -232,9 +233,8 @@ public abstract class AnnotationUtils { @@ -232,9 +233,8 @@ public abstract class AnnotationUtils {
* <p>The standard {@link Class} API does not provide a mechanism for determining which class
* in an inheritance hierarchy actually declares an {@link Annotation}, so we need to handle
* this explicitly.
* @param annotationType the Class object corresponding to the annotation type
* @param clazz the Class object corresponding to the class on which to check for the annotation,
* or {@code null}
* @param annotationType the annotation type to look for, both locally and as a meta-annotation
* @param clazz the class on which to check for the annotation (may be {@code null})
* @return the first {@link Class} in the inheritance hierarchy of the specified {@code clazz}
* which declares an annotation for the specified {@code annotationType}, or {@code null}
* if not found
@ -248,8 +248,10 @@ public abstract class AnnotationUtils { @@ -248,8 +248,10 @@ public abstract class AnnotationUtils {
if (clazz == null || clazz.equals(Object.class)) {
return null;
}
return (isAnnotationDeclaredLocally(annotationType, clazz)) ? clazz : findAnnotationDeclaringClass(
annotationType, clazz.getSuperclass());
if (isAnnotationDeclaredLocally(annotationType, clazz)) {
return clazz;
}
return findAnnotationDeclaringClass(annotationType, clazz.getSuperclass());
}
/**
@ -413,14 +415,13 @@ public abstract class AnnotationUtils { @@ -413,14 +415,13 @@ public abstract class AnnotationUtils {
}
if (nestedAnnotationsAsMap && value instanceof Annotation) {
attrs.put(method.getName(),
getAnnotationAttributes((Annotation) value, classValuesAsString, nestedAnnotationsAsMap));
getAnnotationAttributes((Annotation) value, classValuesAsString, true));
}
else if (nestedAnnotationsAsMap && value instanceof Annotation[]) {
Annotation[] realAnnotations = (Annotation[]) value;
AnnotationAttributes[] mappedAnnotations = new AnnotationAttributes[realAnnotations.length];
for (int i = 0; i < realAnnotations.length; i++) {
mappedAnnotations[i] = getAnnotationAttributes(realAnnotations[i], classValuesAsString,
nestedAnnotationsAsMap);
mappedAnnotations[i] = getAnnotationAttributes(realAnnotations[i], classValuesAsString, true);
}
attrs.put(method.getName(), mappedAnnotations);
}
@ -456,7 +457,8 @@ public abstract class AnnotationUtils { @@ -456,7 +457,8 @@ public abstract class AnnotationUtils {
*/
public static Object getValue(Annotation annotation, String attributeName) {
try {
Method method = annotation.annotationType().getDeclaredMethod(attributeName, new Class[0]);
Method method = annotation.annotationType().getDeclaredMethod(attributeName);
ReflectionUtils.makeAccessible(method);
return method.invoke(annotation);
}
catch (Exception ex) {
@ -506,8 +508,7 @@ public abstract class AnnotationUtils { @@ -506,8 +508,7 @@ public abstract class AnnotationUtils {
*/
public static Object getDefaultValue(Class<? extends Annotation> annotationType, String attributeName) {
try {
Method method = annotationType.getDeclaredMethod(attributeName, new Class[0]);
return method.getDefaultValue();
return annotationType.getDeclaredMethod(attributeName).getDefaultValue();
}
catch (Exception ex) {
return null;

18
spring-core/src/main/java/org/springframework/core/env/EnumerablePropertySource.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2014 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.
@ -18,6 +18,7 @@ package org.springframework.core.env; @@ -18,6 +18,7 @@ package org.springframework.core.env;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
/**
@ -53,21 +54,22 @@ public abstract class EnumerablePropertySource<T> extends PropertySource<T> { @@ -53,21 +54,22 @@ public abstract class EnumerablePropertySource<T> extends PropertySource<T> {
super(name, source);
}
/**
* Return the names of all properties contained by the {@linkplain #getSource()
* source} object (never {@code null}).
* Return the names of all properties contained by the
* {@linkplain #getSource() source} object (never {@code null}).
*/
public abstract String[] getPropertyNames();
/**
* Return whether this {@code PropertySource} contains a property with the given name.
* <p>This implementation checks for the presence of the given name within
* the {@link #getPropertyNames()} array.
* @param name the property to find
* <p>This implementation checks for the presence of the given name within the
* {@link #getPropertyNames()} array.
* @param name the name of the property to find
*/
public boolean containsProperty(String name) {
Assert.notNull(name, "property name must not be null");
for (String candidate : this.getPropertyNames()) {
Assert.notNull(name, "Property name must not be null");
for (String candidate : getPropertyNames()) {
if (candidate.equals(name)) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("PropertySource [%s] contains '%s'", getName(), name));

91
spring-core/src/main/java/org/springframework/core/env/PropertySource.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2014 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.
@ -18,7 +18,9 @@ package org.springframework.core.env; @@ -18,7 +18,9 @@ package org.springframework.core.env;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Abstract base class representing a source of name/value property pairs. The underlying
@ -55,12 +57,13 @@ import org.springframework.util.Assert; @@ -55,12 +57,13 @@ import org.springframework.util.Assert;
*/
public abstract class PropertySource<T> {
protected final Log logger = LogFactory.getLog(this.getClass());
protected final Log logger = LogFactory.getLog(getClass());
protected final String name;
protected final T source;
/**
* Create a new {@code PropertySource} with the given name and source object.
*/
@ -74,15 +77,15 @@ public abstract class PropertySource<T> { @@ -74,15 +77,15 @@ public abstract class PropertySource<T> {
/**
* Create a new {@code PropertySource} with the given name and with a new {@code Object}
* instance as the underlying source.
* <p>Often useful in testing scenarios when creating
* anonymous implementations that never query an actual source, but rather return
* hard-coded values.
* <p>Often useful in testing scenarios when creating anonymous implementations that
* never query an actual source but rather return hard-coded values.
*/
@SuppressWarnings("unchecked")
public PropertySource(String name) {
this(name, (T) new Object());
}
/**
* Return the name of this {@code PropertySource}
*/
@ -94,91 +97,75 @@ public abstract class PropertySource<T> { @@ -94,91 +97,75 @@ public abstract class PropertySource<T> {
* Return the underlying source object for this {@code PropertySource}.
*/
public T getSource() {
return source;
return this.source;
}
/**
* Return whether this {@code PropertySource} contains the given name.
* <p>This implementation simply checks for a null return value
* from {@link #getProperty(String)}. Subclasses may wish to
* implement a more efficient algorithm if possible.
* <p>This implementation simply checks for a {@code null} return value
* from {@link #getProperty(String)}. Subclasses may wish to implement
* a more efficient algorithm if possible.
* @param name the property name to find
*/
public boolean containsProperty(String name) {
return this.getProperty(name) != null;
return (getProperty(name) != null);
}
/**
* Return the value associated with the given name, {@code null} if not found.
* Return the value associated with the given name,
* or {@code null} if not found.
* @param name the property to find
* @see PropertyResolver#getRequiredProperty(String)
*/
public abstract Object getProperty(String name);
/**
* Return a hashcode derived from the {@code name} property of this {@code PropertySource}
* object.
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
return result;
}
/**
* This {@code PropertySource} object is equal to the given object if:
* <ul>
* <li>they are the same instance
* <li>the {@code name} properties for both objects are equal
* <li>they are the same instance
* <li>the {@code name} properties for both objects are equal
* </ul>
*
* <P>No properties other than {@code name} are evaluated.
* <p>No properties other than {@code name} are evaluated.
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof PropertySource))
return false;
PropertySource<?> other = (PropertySource<?>) obj;
if (this.name == null) {
if (other.name != null)
return false;
} else if (!this.name.equals(other.name))
return false;
return true;
return (this == obj || (obj instanceof PropertySource &&
ObjectUtils.nullSafeEquals(this.name, ((PropertySource<?>) obj).name)));
}
/**
* Return a hash code derived from the {@code name} property
* of this {@code PropertySource} object.
*/
@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.name);
}
/**
* Produce concise output (type and name) if the current log level does not include
* debug. If debug is enabled, produce verbose output including hashcode of the
* debug. If debug is enabled, produce verbose output including the hash code of the
* PropertySource instance and every name/value property pair.
*
* This variable verbosity is useful as a property source such as system properties
* <p>This variable verbosity is useful as a property source such as system properties
* or environment variables may contain an arbitrary number of property pairs,
* potentially leading to difficult to read exception and log messages.
*
* @see Log#isDebugEnabled()
*/
@Override
public String toString() {
if (logger.isDebugEnabled()) {
return String.format("%s@%s [name='%s', properties=%s]",
this.getClass().getSimpleName(), System.identityHashCode(this), this.name, this.source);
getClass().getSimpleName(), System.identityHashCode(this), this.name, this.source);
}
else {
return String.format("%s [name='%s']", getClass().getSimpleName(), this.name);
}
return String.format("%s [name='%s']",
this.getClass().getSimpleName(), this.name);
}
/**
* Return a {@code PropertySource} implementation intended for collection comparison purposes only.
*
* <p>Primarily for internal use, but given a collection of {@code PropertySource} objects, may be
* used as follows:
* <pre class="code">
@ -189,11 +176,9 @@ public abstract class PropertySource<T> { @@ -189,11 +176,9 @@ public abstract class PropertySource<T> {
* assert sources.contains(PropertySource.named("sourceB"));
* assert !sources.contains(PropertySource.named("sourceC"));
* }</pre>
*
* The returned {@code PropertySource} will throw {@code UnsupportedOperationException}
* if any methods other than {@code equals(Object)}, {@code hashCode()}, and {@code toString()}
* are called.
*
* @param name the name of the comparison {@code PropertySource} to be created and returned.
*/
public static PropertySource<?> named(String name) {
@ -209,7 +194,6 @@ public abstract class PropertySource<T> { @@ -209,7 +194,6 @@ public abstract class PropertySource<T> {
* {@code ApplicationContext}. In such cases, a stub should be used to hold the
* intended default position/order of the property source, then be replaced
* during context refresh.
*
* @see org.springframework.context.support.AbstractApplicationContext#initPropertySources()
* @see org.springframework.web.context.support.StandardServletEnvironment
* @see org.springframework.web.context.support.ServletContextPropertySource
@ -221,7 +205,7 @@ public abstract class PropertySource<T> { @@ -221,7 +205,7 @@ public abstract class PropertySource<T> {
}
/**
* Always return {@code null}.
* Always returns {@code null}.
*/
@Override
public String getProperty(String name) {
@ -236,8 +220,7 @@ public abstract class PropertySource<T> { @@ -236,8 +220,7 @@ public abstract class PropertySource<T> {
static class ComparisonPropertySource extends StubPropertySource {
private static final String USAGE_ERROR =
"ComparisonPropertySource instances are for collection comparison " +
"use only";
"ComparisonPropertySource instances are for use with collection comparison only";
public ComparisonPropertySource(String name) {
super(name);

17
spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java

@ -29,8 +29,8 @@ import org.springframework.util.ReflectionUtils; @@ -29,8 +29,8 @@ import org.springframework.util.ReflectionUtils;
/**
* Oracle-specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}.
* Supports a feature for including synonyms in the metadata lookup. Also supports lookup of current schema using
* the sys_context.
* Supports a feature for including synonyms in the metadata lookup. Also supports lookup of current schema
* using the sys_context.
*
* <p>Thanks to Mike Youngstrom and Bruce Campbell for submitting the original suggestion for the Oracle
* current schema lookup implementation.
@ -56,9 +56,10 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { @@ -56,9 +56,10 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
lookupDefaultSchema(databaseMetaData);
}
@Override
protected String getDefaultSchema() {
if (defaultSchema != null) {
if (this.defaultSchema != null) {
return defaultSchema;
}
return super.getDefaultSchema();
@ -107,7 +108,7 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { @@ -107,7 +108,7 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
ReflectionUtils.makeAccessible(getIncludeSynonyms);
originalValueForIncludeSynonyms = (Boolean) getIncludeSynonyms.invoke(con);
setIncludeSynonyms = con.getClass().getMethod("setIncludeSynonyms", new Class[] {boolean.class});
setIncludeSynonyms = con.getClass().getMethod("setIncludeSynonyms", boolean.class);
ReflectionUtils.makeAccessible(setIncludeSynonyms);
setIncludeSynonyms.invoke(con, Boolean.TRUE);
}
@ -126,9 +127,7 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { @@ -126,9 +127,7 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
}
/*
* Oracle implementation for detecting current schema
*
* @param databaseMetaData
* Oracle-based implementation for detecting the current schema.
*/
private void lookupDefaultSchema(DatabaseMetaData databaseMetaData) {
try {
@ -144,7 +143,9 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { @@ -144,7 +143,9 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
cstmt.close();
}
}
} catch (Exception ignore) {}
}
catch (Exception ignore) {
}
}
}

58
spring-test/src/main/java/org/springframework/test/context/TestContextManager.java

@ -28,27 +28,24 @@ import org.apache.commons.logging.Log; @@ -28,27 +28,24 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
/**
* <p>
* {@code TestContextManager} is the main entry point into the
* <em>Spring TestContext Framework</em>, which provides support for loading and
* accessing {@link ApplicationContext application contexts}, dependency
* injection of test instances,
* {@link org.springframework.transaction.annotation.Transactional
* transactional} execution of test methods, etc.
* </p>
* <p>
* Specifically, a {@code TestContextManager} is responsible for managing a
* {@code TestContextManager} is the main entry point into the <em>Spring
* TestContext Framework</em>, which provides support for loading and accessing
* {@link org.springframework.context.ApplicationContext application contexts},
* dependency injection of test instances,
* {@link org.springframework.transaction.annotation.Transactional transactional}
* execution of test methods, etc.
*
* <p>Specifically, a {@code TestContextManager} is responsible for managing a
* single {@link TestContext} and signaling events to all registered
* {@link TestExecutionListener TestExecutionListeners} at well defined test
* execution points:
* </p>
*
* <ul>
* <li>{@link #beforeTestClass() before test class execution}: prior to any
* <em>before class methods</em> of a particular testing framework (e.g., JUnit
@ -85,9 +82,10 @@ public class TestContextManager { @@ -85,9 +82,10 @@ public class TestContextManager {
private static final Log logger = LogFactory.getLog(TestContextManager.class);
/**
* Cache of Spring application contexts. This needs to be static, as tests
* may be destroyed and recreated between running individual test methods,
* for example with JUnit.
* Cache of Spring application contexts.
* <p>This needs to be static, since test instances may be destroyed and
* recreated between invocations of individual test methods, as is the case
* with JUnit.
*/
static final ContextCache contextCache = new ContextCache();
@ -97,7 +95,11 @@ public class TestContextManager { @@ -97,7 +95,11 @@ public class TestContextManager {
/**
* Delegates to {@link #TestContextManager(Class, String)} with a value of
* Construct a new {@code TestContextManager} for the specified {@linkplain Class test class}
* and automatically {@link #registerTestExecutionListeners register} the
* {@link TestExecutionListener TestExecutionListeners} configured for the test class
* via the {@link TestExecutionListeners &#064;TestExecutionListeners} annotation.
* <p>Delegates to {@link #TestContextManager(Class, String)} with a value of
* {@code null} for the default {@code ContextLoader} class name.
*/
public TestContextManager(Class<?> testClass) {
@ -105,23 +107,23 @@ public class TestContextManager { @@ -105,23 +107,23 @@ public class TestContextManager {
}
/**
* Constructs a new {@code TestContextManager} for the specified {@linkplain Class
* test class} and automatically {@link #registerTestExecutionListeners registers} the
* Construct a new {@code TestContextManager} for the specified {@linkplain Class test class}
* and automatically {@link #registerTestExecutionListeners register} the
* {@link TestExecutionListener TestExecutionListeners} configured for the test class
* via the {@link TestExecutionListeners &#064;TestExecutionListeners} annotation.
* @param testClass the test class to be managed
* @param defaultContextLoaderClassName the name of the default {@code ContextLoader}
* class to use (may be {@code null})
* @see #registerTestExecutionListeners(TestExecutionListener...)
* @param defaultContextLoaderClassName the name of the default {@code ContextLoader} class
* to use (may be {@code null})
* @see #registerTestExecutionListeners
*/
public TestContextManager(Class<?> testClass, String defaultContextLoaderClassName) {
this.testContext = new TestContext(testClass, contextCache, defaultContextLoaderClassName);
registerTestExecutionListeners(retrieveTestExecutionListeners(testClass));
}
/**
* Returns the {@link TestContext} managed by this
* {@code TestContextManager}.
* Get the {@link TestContext} managed by this {@code TestContextManager}.
*/
protected final TestContext getTestContext() {
return this.testContext;
@ -183,7 +185,8 @@ public class TestContextManager { @@ -183,7 +185,8 @@ public class TestContextManager {
logger.debug("@TestExecutionListeners is not present for class [" + clazz + "]: using defaults.");
}
classesList.addAll(getDefaultTestExecutionListenerClasses());
} else {
}
else {
// Traverse the class hierarchy...
while (declaringClass != null) {
TestExecutionListeners testExecutionListeners = declaringClass.getAnnotation(annotationType);
@ -201,7 +204,8 @@ public class TestContextManager { @@ -201,7 +204,8 @@ public class TestContextManager {
ObjectUtils.nullSafeToString(listenerClasses));
logger.error(msg);
throw new IllegalStateException(msg);
} else if (!ObjectUtils.isEmpty(valueListenerClasses)) {
}
else if (!ObjectUtils.isEmpty(valueListenerClasses)) {
listenerClasses = valueListenerClasses;
}
@ -264,7 +268,7 @@ public class TestContextManager { @@ -264,7 +268,7 @@ public class TestContextManager {
* @see #getTestExecutionListeners()
*/
public void beforeTestClass() throws Exception {
final Class<?> testClass = getTestContext().getTestClass();
Class<?> testClass = getTestContext().getTestClass();
if (logger.isTraceEnabled()) {
logger.trace("beforeTestClass(): class [" + testClass + "]");
}
@ -421,7 +425,7 @@ public class TestContextManager { @@ -421,7 +425,7 @@ public class TestContextManager {
* @see #getTestExecutionListeners()
*/
public void afterTestClass() throws Exception {
final Class<?> testClass = getTestContext().getTestClass();
Class<?> testClass = getTestContext().getTestClass();
if (logger.isTraceEnabled()) {
logger.trace("afterTestClass(): class [" + testClass + "]");
}

31
spring-web/src/test/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContextTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2014 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.
@ -16,9 +16,8 @@ @@ -16,9 +16,8 @@
package org.springframework.web.context.support;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
@ -26,18 +25,17 @@ import org.springframework.context.annotation.Bean; @@ -26,18 +25,17 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
/**
* @author Chris Beams
* @author Juergen Hoeller
*/
public class AnnotationConfigWebApplicationContextTests {
@Test
public void registerSingleClass() {
AnnotationConfigWebApplicationContext ctx =
new AnnotationConfigWebApplicationContext();
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(Config.class);
ctx.refresh();
@ -47,8 +45,7 @@ public class AnnotationConfigWebApplicationContextTests { @@ -47,8 +45,7 @@ public class AnnotationConfigWebApplicationContextTests {
@Test
public void configLocationWithSingleClass() {
AnnotationConfigWebApplicationContext ctx =
new AnnotationConfigWebApplicationContext();
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.setConfigLocation(Config.class.getName());
ctx.refresh();
@ -56,10 +53,19 @@ public class AnnotationConfigWebApplicationContextTests { @@ -56,10 +53,19 @@ public class AnnotationConfigWebApplicationContextTests {
assertNotNull(bean);
}
@Test
public void configLocationWithBasePackage() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.setConfigLocation("org.springframework.web.context.support");
ctx.refresh();
TestBean bean = ctx.getBean(TestBean.class);
assertNotNull(bean);
}
@Test
public void withBeanNameGenerator() {
AnnotationConfigWebApplicationContext ctx =
new AnnotationConfigWebApplicationContext();
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.setBeanNameGenerator(new AnnotationBeanNameGenerator() {
@Override
public String generateBeanName(BeanDefinition definition,
@ -75,14 +81,15 @@ public class AnnotationConfigWebApplicationContextTests { @@ -75,14 +81,15 @@ public class AnnotationConfigWebApplicationContextTests {
@Configuration("myConfig")
static class Config {
@Bean
public TestBean myTestBean() {
return new TestBean();
}
}
static class NotConfigurationAnnotated { }
static class TestBean { }
static class TestBean {
}
}

Loading…
Cancel
Save