Polishing

(cherry picked from commit e903106)
This commit is contained in:
Juergen Hoeller 2016-02-04 20:00:00 +01:00
parent e48315549e
commit 4418331429
5 changed files with 37 additions and 48 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 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.
@ -50,29 +50,20 @@ import org.springframework.util.StringUtils;
* reloading files based on timestamp changes, but also of loading properties files
* with a specific character encoding. It will detect XML property files as well.
*
* <p>In contrast to {@link ResourceBundleMessageSource}, this class supports
* reloading of properties files through the {@link #setCacheSeconds "cacheSeconds"}
* setting, and also through programmatically clearing the properties cache.
* Since application servers typically cache all files loaded from the classpath,
* it is necessary to store resources somewhere else (for example, in the
* "WEB-INF" directory of a web app). Otherwise changes of files in the
* classpath will <i>not</i> be reflected in the application.
*
* <p>Note that the base names set as {@link #setBasenames "basenames"} property
* <p>Note that the basenames set as {@link #setBasenames "basenames"} property
* are treated in a slightly different fashion than the "basenames" property of
* {@link ResourceBundleMessageSource}. It follows the basic ResourceBundle rule of not
* specifying file extension or language codes, but can refer to any Spring resource
* location (instead of being restricted to classpath resources). With a "classpath:"
* prefix, resources can still be loaded from the classpath, but "cacheSeconds" values
* other than "-1" (caching forever) will not work in this case.
*
* <p>This MessageSource implementation is usually slightly faster than
* {@link ResourceBundleMessageSource}, which builds on {@link java.util.ResourceBundle}
* - in the default mode, i.e. when caching forever. With "cacheSeconds" set to 1,
* message lookup takes about twice as long - with the benefit that changes in
* individual properties files are detected with a maximum delay of 1 second.
* Higher "cacheSeconds" values usually <i>do not</i> make a significant difference.
* other than "-1" (caching forever) might not work reliably in this case.
*
* <p>For a typical web application, message files could be placed into {@code WEB-INF}:
* e.g. a "WEB-INF/messages" basename would fine a "WEB-INF/messages.properties",
* "WEB-INF/messages_en.properties" etc arrangement as well as "WEB-INF/messages.xml",
* "WEB-INF/messages_en.xml" etc. Note that message definitions in a <i>previous</i>
* resource bundle will override ones in a later bundle, due to sequential lookup.
* <p>This MessageSource can easily be used outside of an
* {@link org.springframework.context.ApplicationContext}: It will use a
* {@link org.springframework.core.io.DefaultResourceLoader} as default,
@ -244,6 +235,7 @@ public class ReloadableResourceBundleMessageSource extends AbstractMessageSource
* <p>Default is "true": This behavior is new as of Spring Framework 4.1,
* minimizing contention between threads. If you prefer the old behavior,
* i.e. to fully block on refresh, switch this flag to "false".
* @since 4.1
* @see #setCacheSeconds
*/
public void setConcurrentRefresh(boolean concurrentRefresh) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 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.
@ -51,11 +51,11 @@ import org.springframework.util.StringUtils;
* base class. The caching provided by this MessageSource is significantly faster
* than the built-in caching of the {@code java.util.ResourceBundle} class.
*
* <p>Unfortunately, {@code java.util.ResourceBundle} caches loaded bundles
* forever: Reloading a bundle during VM execution is <i>not</i> possible.
* As this MessageSource relies on ResourceBundle, it faces the same limitation.
* Consider {@link ReloadableResourceBundleMessageSource} for an alternative
* that is capable of refreshing the underlying bundle files.
* <p>The basenames follow {@link java.util.ResourceBundle} conventions: essentially,
* a fully-qualified classpath location. If it doesn't contain a package qualifier
* (such as {@code org.mypackage}), it will be resolved from the classpath root.
* Note that the JDK's standard ResourceBundle treats dots as package separators:
* This means that "test.theme" is effectively equivalent to "test/theme".
*
* @author Rod Johnson
* @author Juergen Hoeller
@ -404,8 +404,7 @@ public class ResourceBundleMessageSource extends AbstractMessageSource implement
*/
@Override
public String toString() {
return getClass().getName() + ": basenames=[" +
StringUtils.arrayToCommaDelimitedString(this.basenames) + "]";
return getClass().getName() + ": basenames=[" + StringUtils.arrayToCommaDelimitedString(this.basenames) + "]";
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2016 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.
@ -103,6 +103,7 @@ public class ExponentialBackOff implements BackOff {
this.multiplier = multiplier;
}
/**
* The initial interval in milliseconds.
*/
@ -183,12 +184,12 @@ public class ExponentialBackOff implements BackOff {
@Override
public long nextBackOff() {
if (currentElapsedTime >= maxElapsedTime) {
if (this.currentElapsedTime >= maxElapsedTime) {
return STOP;
}
long nextInterval = computeNextInterval();
currentElapsedTime += nextInterval;
this.currentElapsedTime += nextInterval;
return nextInterval;
}
@ -205,7 +206,7 @@ public class ExponentialBackOff implements BackOff {
else {
this.currentInterval = multiplyInterval(maxInterval);
}
return currentInterval;
return this.currentInterval;
}
private long multiplyInterval(long maxInterval) {
@ -217,9 +218,8 @@ public class ExponentialBackOff implements BackOff {
@Override
public String toString() {
String i = (this.currentInterval < 0 ? "n/a" : this.currentInterval + "ms");
final StringBuilder sb = new StringBuilder("ExponentialBackOff{");
sb.append("currentInterval=").append(i);
StringBuilder sb = new StringBuilder("ExponentialBackOff{");
sb.append("currentInterval=").append(this.currentInterval < 0 ? "n/a" : this.currentInterval + "ms");
sb.append(", multiplier=").append(getMultiplier());
sb.append('}');
return sb.toString();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2016 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.
@ -57,6 +57,7 @@ public class FixedBackOff implements BackOff {
this.maxAttempts = maxAttempts;
}
/**
* Set the interval between two attempts in milliseconds.
*/
@ -110,14 +111,13 @@ public class FixedBackOff implements BackOff {
public String toString() {
final StringBuilder sb = new StringBuilder("FixedBackOff{");
sb.append("interval=").append(FixedBackOff.this.interval);
String attemptValue = (FixedBackOff.this.maxAttempts == Long.MAX_VALUE ? "unlimited"
: String.valueOf(FixedBackOff.this.maxAttempts));
String attemptValue = (FixedBackOff.this.maxAttempts == Long.MAX_VALUE ?
"unlimited" : String.valueOf(FixedBackOff.this.maxAttempts));
sb.append(", currentAttempts=").append(this.currentAttempts);
sb.append(", maxAttempts=").append(attemptValue);
sb.append('}');
return sb.toString();
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 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.
@ -175,7 +175,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
private Executor taskExecutor;
private BackOff backOff = createDefaultBackOff(DEFAULT_RECOVERY_INTERVAL);
private BackOff backOff = new FixedBackOff(DEFAULT_RECOVERY_INTERVAL, Long.MAX_VALUE);
private int cacheLevel = CACHE_AUTO;
@ -229,6 +229,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
* attempt to recover.
* <p>The {@link #setRecoveryInterval(long) recovery interval} is ignored
* when this property is set.
* @since 4.1
*/
public void setBackOff(BackOff backOff) {
this.backOff = backOff;
@ -244,7 +245,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
* @see #handleListenerSetupFailure
*/
public void setRecoveryInterval(long recoveryInterval) {
this.backOff = createDefaultBackOff(recoveryInterval);
this.backOff = new FixedBackOff(recoveryInterval, Long.MAX_VALUE);
}
/**
@ -941,7 +942,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
StringBuilder msg = new StringBuilder();
msg.append("Stopping container for destination '")
.append(getDestinationDescription())
.append("' - back off policy does not allow ").append("for further attempts.");
.append("': back-off policy does not allow ").append("for further attempts.");
logger.error(msg.toString());
stop();
}
@ -968,10 +969,11 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
}
/**
* Apply the next back off time using the specified {@link BackOffExecution}.
* <p>Return {@code true} if the back off period has been applied and a new
* Apply the next back-off time using the specified {@link BackOffExecution}.
* <p>Return {@code true} if the back-off period has been applied and a new
* attempt to recover should be made, {@code false} if no further attempt
* should be made.
* @since 4.1
*/
protected boolean applyBackOffTime(BackOffExecution execution) {
long interval = execution.nextBackOff();
@ -990,10 +992,6 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
return true;
}
private FixedBackOff createDefaultBackOff(long interval) {
return new FixedBackOff(interval, Long.MAX_VALUE);
}
/**
* Return whether this listener container is currently in a recovery attempt.
* <p>May be used to detect recovery phases but also the end of a recovery phase,
@ -1205,7 +1203,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
}
/**
* Apply the back off time once. In a regular scenario, the back off is only applied if we
* Apply the back-off time once. In a regular scenario, the back-off is only applied if we
* failed to recover with the broker. This additional sleep period avoids a burst retry
* scenario when the broker is actually up but something else if failing (i.e. listener
* specific).