Browse Source

Polishing

pull/528/merge
Juergen Hoeller 12 years ago
parent
commit
be5f2a8b4e
  1. 14
      spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.java
  2. 22
      spring-context/src/main/java/org/springframework/scheduling/annotation/AnnotationAsyncExecutionInterceptor.java
  3. 19
      spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java
  4. 18
      spring-core/src/main/java/org/springframework/core/env/EnumerablePropertySource.java
  5. 71
      spring-core/src/main/java/org/springframework/core/env/PropertySource.java
  6. 2
      spring-core/src/main/java/org/springframework/util/CollectionUtils.java

14
spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.java

@ -19,11 +19,11 @@ package org.springframework.aop.interceptor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
/** /**
* A strategy for handling uncaught exception thrown by asynchronous methods. * A strategy for handling uncaught exceptions thrown from asynchronous methods.
* *
* <p>An asynchronous method usually returns a {@link java.util.concurrent.Future} * <p>An asynchronous method usually returns a {@link java.util.concurrent.Future}
* instance that gives access to the underlying exception. When the method * instance that gives access to the underlying exception. When the method does
* does not provide that return type, this handler can be used to managed such * not provide that return type, this handler can be used to managed such
* uncaught exceptions. * uncaught exceptions.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
@ -32,11 +32,11 @@ import java.lang.reflect.Method;
public interface AsyncUncaughtExceptionHandler { public interface AsyncUncaughtExceptionHandler {
/** /**
* Handle the given uncaught error thrown while processing * Handle the given uncaught exception thrown from an asynchronous method.
* an asynchronous method. * @param ex the exception thrown from the asynchronous method
* @param ex the exception thrown by invoking the async operation * @param method the asynchronous method
* @param method the async operation
* @param params the parameters used to invoked the method * @param params the parameters used to invoked the method
*/ */
void handleUncaughtException(Throwable ex, Method method, Object... params); void handleUncaughtException(Throwable ex, Method method, Object... params);
} }

22
spring-context/src/main/java/org/springframework/scheduling/annotation/AnnotationAsyncExecutionInterceptor.java

@ -40,28 +40,28 @@ import org.springframework.core.annotation.AnnotationUtils;
public class AnnotationAsyncExecutionInterceptor extends AsyncExecutionInterceptor { public class AnnotationAsyncExecutionInterceptor extends AsyncExecutionInterceptor {
/** /**
* Create a new {@code AnnotationAsyncExecutionInterceptor} with the given executor. * Create a new {@code AnnotationAsyncExecutionInterceptor} with the given executor
* and a simple {@link AsyncUncaughtExceptionHandler}.
* @param defaultExecutor the executor to be used by default if no more specific * @param defaultExecutor the executor to be used by default if no more specific
* executor has been qualified at the method level using {@link Async#value()} * executor has been qualified at the method level using {@link Async#value()}
* @param exceptionHandler the {@link AsyncUncaughtExceptionHandler} to use to
* handle exceptions thrown by asynchronous method executions with {@code void}
* return type
*/ */
public AnnotationAsyncExecutionInterceptor(Executor defaultExecutor, public AnnotationAsyncExecutionInterceptor(Executor defaultExecutor) {
AsyncUncaughtExceptionHandler exceptionHandler) { this(defaultExecutor, new SimpleAsyncUncaughtExceptionHandler());
super(defaultExecutor, exceptionHandler);
} }
/** /**
* Create a new {@code AnnotationAsyncExecutionInterceptor} with the given executor * Create a new {@code AnnotationAsyncExecutionInterceptor} with the given executor.
* and a simple {@link AsyncUncaughtExceptionHandler}.
* @param defaultExecutor the executor to be used by default if no more specific * @param defaultExecutor the executor to be used by default if no more specific
* executor has been qualified at the method level using {@link Async#value()} * executor has been qualified at the method level using {@link Async#value()}
* @param exceptionHandler the {@link AsyncUncaughtExceptionHandler} to use to
* handle exceptions thrown by asynchronous method executions with {@code void}
* return type
*/ */
public AnnotationAsyncExecutionInterceptor(Executor defaultExecutor) { public AnnotationAsyncExecutionInterceptor(Executor defaultExecutor, AsyncUncaughtExceptionHandler exceptionHandler) {
this(defaultExecutor, new SimpleAsyncUncaughtExceptionHandler()); super(defaultExecutor, exceptionHandler);
} }
/** /**
* Return the qualifier or bean name of the executor to be used when executing the * Return the qualifier or bean name of the executor to be used when executing the
* given method, specified via {@link Async#value} at the method or declaring * given method, specified via {@link Async#value} at the method or declaring

19
spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java

@ -23,6 +23,7 @@ import java.lang.annotation.Target;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.aop.scope.ScopedObject; import org.springframework.aop.scope.ScopedObject;
import org.springframework.aop.scope.ScopedProxyUtils; import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.FactoryBean;
@ -86,8 +87,7 @@ public class ConfigurationClassPostProcessorTests {
*/ */
@Test @Test
public void alreadyLoadedConfigurationClasses() { public void alreadyLoadedConfigurationClasses() {
beanFactory.registerBeanDefinition("unloadedConfig", new RootBeanDefinition(UnloadedConfig.class.getName(), beanFactory.registerBeanDefinition("unloadedConfig", new RootBeanDefinition(UnloadedConfig.class.getName()));
null, null));
beanFactory.registerBeanDefinition("loadedConfig", new RootBeanDefinition(LoadedConfig.class)); beanFactory.registerBeanDefinition("loadedConfig", new RootBeanDefinition(LoadedConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor(); ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory); pp.postProcessBeanFactory(beanFactory);
@ -208,8 +208,8 @@ public class ConfigurationClassPostProcessorTests {
public void postProcessorDoesNotOverrideRegularBeanDefinitionsEvenWithScopedProxy() { public void postProcessorDoesNotOverrideRegularBeanDefinitionsEvenWithScopedProxy() {
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class); RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
rbd.setResource(new DescriptiveResource("XML or something")); rbd.setResource(new DescriptiveResource("XML or something"));
BeanDefinitionHolder proxied = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(rbd, "bar"), BeanDefinitionHolder proxied = ScopedProxyUtils.createScopedProxy(
beanFactory, true); new BeanDefinitionHolder(rbd, "bar"), beanFactory, true);
beanFactory.registerBeanDefinition("bar", proxied.getBeanDefinition()); beanFactory.registerBeanDefinition("bar", proxied.getBeanDefinition());
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(SingletonBeanConfig.class)); beanFactory.registerBeanDefinition("config", new RootBeanDefinition(SingletonBeanConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor(); ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
@ -296,8 +296,7 @@ public class ConfigurationClassPostProcessorTests {
RootBeanDefinition bd = new RootBeanDefinition(RepositoryInjectionBean.class); RootBeanDefinition bd = new RootBeanDefinition(RepositoryInjectionBean.class);
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
beanFactory.registerBeanDefinition("annotatedBean", bd); beanFactory.registerBeanDefinition("annotatedBean", bd);
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition( beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(ScopedProxyRepositoryConfiguration.class));
ScopedProxyRepositoryConfiguration.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor(); ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory); pp.postProcessBeanFactory(beanFactory);
beanFactory.freezeConfiguration(); beanFactory.freezeConfiguration();
@ -332,8 +331,7 @@ public class ConfigurationClassPostProcessorTests {
RootBeanDefinition bd = new RootBeanDefinition(RepositoryFactoryBeanInjectionBean.class); RootBeanDefinition bd = new RootBeanDefinition(RepositoryFactoryBeanInjectionBean.class);
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
beanFactory.registerBeanDefinition("annotatedBean", bd); beanFactory.registerBeanDefinition("annotatedBean", bd);
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition( beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryFactoryBeanConfiguration.class));
RepositoryFactoryBeanConfiguration.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor(); ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory); pp.postProcessBeanFactory(beanFactory);
beanFactory.preInstantiateSingletons(); beanFactory.preInstantiateSingletons();
@ -374,8 +372,7 @@ public class ConfigurationClassPostProcessorTests {
@Test @Test
public void genericsBasedInjectionWithWildcardWithGenericExtendsMatch() { public void genericsBasedInjectionWithWildcardWithGenericExtendsMatch() {
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition( beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(WildcardWithGenericExtendsConfiguration.class));
WildcardWithGenericExtendsConfiguration.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor(); ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory); pp.postProcessBeanFactory(beanFactory);
@ -574,7 +571,6 @@ public class ConfigurationClassPostProcessorTests {
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Repository<String> stringRepo() { public Repository<String> stringRepo() {
return new Repository<String>() { return new Repository<String>() {
@Override @Override
public String toString() { public String toString() {
return "Repository<String>"; return "Repository<String>";
@ -586,7 +582,6 @@ public class ConfigurationClassPostProcessorTests {
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Repository<Integer> integerRepo() { public Repository<Integer> integerRepo() {
return new Repository<Integer>() { return new Repository<Integer>() {
@Override @Override
public String toString() { public String toString() {
return "Repository<Integer>"; return "Repository<Integer>";

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

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

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

@ -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"); * 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.
@ -18,7 +18,9 @@ package org.springframework.core.env;
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.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/** /**
* Abstract base class representing a source of name/value property pairs. The underlying * Abstract base class representing a source of name/value property pairs. The underlying
@ -55,12 +57,13 @@ import org.springframework.util.Assert;
*/ */
public abstract class PropertySource<T> { 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 String name;
protected final T source; protected final T source;
/** /**
* Create a new {@code PropertySource} with the given name and source object. * Create a new {@code PropertySource} with the given name and source object.
*/ */
@ -83,6 +86,7 @@ public abstract class PropertySource<T> {
this(name, (T) new Object()); this(name, (T) new Object());
} }
/** /**
* Return the name of this {@code PropertySource} * Return the name of this {@code PropertySource}
*/ */
@ -94,7 +98,7 @@ public abstract class PropertySource<T> {
* Return the underlying source object for this {@code PropertySource}. * Return the underlying source object for this {@code PropertySource}.
*/ */
public T getSource() { public T getSource() {
return source; return this.source;
} }
/** /**
@ -105,27 +109,17 @@ public abstract class PropertySource<T> {
* @param name the property name to find * @param name the property name to find
*/ */
public boolean containsProperty(String name) { 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 * @param name the property to find
* @see PropertyResolver#getRequiredProperty(String) * @see PropertyResolver#getRequiredProperty(String)
*/ */
public abstract Object getProperty(String name); 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: * This {@code PropertySource} object is equal to the given object if:
@ -133,52 +127,46 @@ public abstract class PropertySource<T> {
* <li>they are the same instance * <li>they are the same instance
* <li>the {@code name} properties for both objects are equal * <li>the {@code name} properties for both objects are equal
* </ul> * </ul>
* * <p>No properties other than {@code name} are evaluated.
* <P>No properties other than {@code name} are evaluated.
*/ */
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) return (this == obj || (obj instanceof PropertySource &&
return true; ObjectUtils.nullSafeEquals(this.name, ((PropertySource<?>) obj).name)));
if (obj == null) }
return false;
if (!(obj instanceof PropertySource)) /**
return false; * Return a hash code derived from the {@code name} property
PropertySource<?> other = (PropertySource<?>) obj; * of this {@code PropertySource} object.
if (this.name == null) { */
if (other.name != null) @Override
return false; public int hashCode() {
} else if (!this.name.equals(other.name)) return ObjectUtils.nullSafeHashCode(this.name);
return false;
return true;
} }
/** /**
* Produce concise output (type and name) if the current log level does not include * Produce concise output (type and name) if the current log level does not include
* debug. If debug is enabled, produce verbose output including hash code of the * debug. If debug is enabled, produce verbose output including hash code of the
* PropertySource instance and every name/value property pair. * PropertySource instance and every name/value property pair.
* * <p>This variable verbosity is useful as a property source such as system properties
* This variable verbosity is useful as a property source such as system properties
* or environment variables may contain an arbitrary number of property pairs, * or environment variables may contain an arbitrary number of property pairs,
* potentially leading to difficult to read exception and log messages. * potentially leading to difficult to read exception and log messages.
*
* @see Log#isDebugEnabled() * @see Log#isDebugEnabled()
*/ */
@Override @Override
public String toString() { public String toString() {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
return String.format("%s@%s [name='%s', properties=%s]", 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. * 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 * <p>Primarily for internal use, but given a collection of {@code PropertySource} objects, may be
* used as follows: * used as follows:
* <pre class="code"> * <pre class="code">
@ -189,11 +177,9 @@ public abstract class PropertySource<T> {
* assert sources.contains(PropertySource.named("sourceB")); * assert sources.contains(PropertySource.named("sourceB"));
* assert !sources.contains(PropertySource.named("sourceC")); * assert !sources.contains(PropertySource.named("sourceC"));
* }</pre> * }</pre>
*
* The returned {@code PropertySource} will throw {@code UnsupportedOperationException} * The returned {@code PropertySource} will throw {@code UnsupportedOperationException}
* if any methods other than {@code equals(Object)}, {@code hashCode()}, and {@code toString()} * if any methods other than {@code equals(Object)}, {@code hashCode()}, and {@code toString()}
* are called. * are called.
*
* @param name the name of the comparison {@code PropertySource} to be created and returned. * @param name the name of the comparison {@code PropertySource} to be created and returned.
*/ */
public static PropertySource<?> named(String name) { public static PropertySource<?> named(String name) {
@ -209,7 +195,6 @@ public abstract class PropertySource<T> {
* {@code ApplicationContext}. In such cases, a stub should be used to hold the * {@code ApplicationContext}. In such cases, a stub should be used to hold the
* intended default position/order of the property source, then be replaced * intended default position/order of the property source, then be replaced
* during context refresh. * during context refresh.
*
* @see org.springframework.context.support.AbstractApplicationContext#initPropertySources() * @see org.springframework.context.support.AbstractApplicationContext#initPropertySources()
* @see org.springframework.web.context.support.StandardServletEnvironment * @see org.springframework.web.context.support.StandardServletEnvironment
* @see org.springframework.web.context.support.ServletContextPropertySource * @see org.springframework.web.context.support.ServletContextPropertySource
@ -221,7 +206,7 @@ public abstract class PropertySource<T> {
} }
/** /**
* Always return {@code null}. * Always returns {@code null}.
*/ */
@Override @Override
public String getProperty(String name) { public String getProperty(String name) {

2
spring-core/src/main/java/org/springframework/util/CollectionUtils.java

@ -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"); * 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.

Loading…
Cancel
Save