Polishing

This commit is contained in:
Juergen Hoeller 2014-07-08 00:59:31 +02:00
parent 1115374188
commit 01264dc673
8 changed files with 78 additions and 69 deletions

View File

@ -22,9 +22,10 @@ import java.util.Map.Entry;
import java.util.Properties;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
/**
* Factory for Map that reads from a YAML source. YAML is a nice human-readable
* Factory for a Map that reads from a YAML source. YAML is a nice human-readable
* format for configuration, and it has some useful hierarchical properties. It's
* more or less a superset of JSON, so it has a lot of similar features. If
* multiple resources are provided the later ones will override entries in the
@ -36,7 +37,6 @@ import org.springframework.beans.factory.FactoryBean;
* bar:
* one: two
* three: four
*
* </pre>
*
* plus (later in the list)
@ -46,7 +46,6 @@ import org.springframework.beans.factory.FactoryBean;
* bar:
* one: 2
* five: six
*
* </pre>
*
* results in an effective input of
@ -57,7 +56,6 @@ import org.springframework.beans.factory.FactoryBean;
* one: 2
* three: four
* five: six
*
* </pre>
*
* Note that the value of "foo" in the first document is not simply replaced
@ -66,35 +64,36 @@ import org.springframework.beans.factory.FactoryBean;
* @author Dave Syer
* @since 4.1
*/
public class YamlMapFactoryBean extends YamlProcessor implements
FactoryBean<Map<String, Object>> {
public class YamlMapFactoryBean extends YamlProcessor implements FactoryBean<Map<String, Object>>, InitializingBean {
private boolean singleton = true;
private Map<String, Object> singletonInstance;
private Map<String, Object> map;
/**
* Set whether a shared 'singleton' Map instance should be
* created, or rather a new Map instance on each request.
* <p>Default is "true" (a shared singleton).
* Set if a singleton should be created, or a new object on each request
* otherwise. Default is {@code true} (a singleton).
*/
public final void setSingleton(boolean singleton) {
public void setSingleton(boolean singleton) {
this.singleton = singleton;
}
@Override
public final boolean isSingleton() {
public boolean isSingleton() {
return this.singleton;
}
@Override
public void afterPropertiesSet() {
if (isSingleton()) {
this.map = createMap();
}
}
@Override
public Map<String, Object> getObject() {
if (!this.singleton || this.singletonInstance == null) {
this.singletonInstance = createProperties();
}
return this.singletonInstance;
return (this.map != null ? this.map : createMap());
}
@Override
@ -102,6 +101,7 @@ public class YamlMapFactoryBean extends YamlProcessor implements
return Map.class;
}
/**
* Template method that subclasses may override to construct the object
* returned by this factory. The default implementation returns the
@ -111,7 +111,7 @@ public class YamlMapFactoryBean extends YamlProcessor implements
* @return the object returned by this factory
* @see #process(java.util.Map, MatchCallback)
*/
protected Map<String, Object> createProperties() {
protected Map<String, Object> createMap() {
final Map<String, Object> result = new LinkedHashMap<String, Object>();
process(new MatchCallback() {
@Override
@ -129,8 +129,7 @@ public class YamlMapFactoryBean extends YamlProcessor implements
Object value = entry.getValue();
Object existing = output.get(key);
if (value instanceof Map && existing instanceof Map) {
Map<String, Object> result = new LinkedHashMap<String, Object>(
(Map) existing);
Map<String, Object> result = new LinkedHashMap<String, Object>((Map) existing);
merge(result, (Map) value);
output.put(key, result);
}

View File

@ -53,6 +53,7 @@ public abstract class YamlProcessor {
private boolean matchDefault = true;
/**
* A map of document matchers allowing callers to selectively use only
* some of the documents in a YAML resource. In YAML documents are
@ -112,10 +113,11 @@ public abstract class YamlProcessor {
* Set locations of YAML {@link Resource resources} to be loaded.
* @see ResolutionMethod
*/
public void setResources(Resource[] resources) {
public void setResources(Resource... resources) {
this.resources = (resources == null ? null : resources.clone());
}
/**
* Provide an opportunity for subclasses to process the Yaml parsed from the supplied
* resources. Each resource is parsed in turn and the documents inside checked against
@ -157,17 +159,16 @@ public abstract class YamlProcessor {
catch (IOException ex) {
handleProcessError(resource, ex);
}
return count > 0;
return (count > 0);
}
private void handleProcessError(Resource resource, IOException ex) {
if (this.resolutionMethod != ResolutionMethod.FIRST_FOUND
&& this.resolutionMethod != ResolutionMethod.OVERRIDE_AND_IGNORE) {
if (this.resolutionMethod != ResolutionMethod.FIRST_FOUND &&
this.resolutionMethod != ResolutionMethod.OVERRIDE_AND_IGNORE) {
throw new IllegalStateException(ex);
}
if (this.logger.isWarnEnabled()) {
this.logger.warn("Could not load map from " + resource + ": "
+ ex.getMessage());
this.logger.warn("Could not load map from " + resource + ": " + ex.getMessage());
}
}
@ -200,7 +201,6 @@ public abstract class YamlProcessor {
}
private boolean process(Map<String, Object> map, MatchCallback callback) {
Properties properties = new Properties();
assignProperties(properties, map, null);
@ -238,8 +238,7 @@ public abstract class YamlProcessor {
return false;
}
private void assignProperties(Properties properties, Map<String, Object> input,
String path) {
private void assignProperties(Properties properties, Map<String, Object> input, String path) {
for (Entry<String, Object> entry : input.entrySet()) {
String key = entry.getKey();
if (StringUtils.hasText(path)) {
@ -276,6 +275,7 @@ public abstract class YamlProcessor {
}
}
/**
* Callback interface used to process properties in a resulting map.
*/
@ -287,9 +287,9 @@ public abstract class YamlProcessor {
* @param map a mutable result map
*/
void process(Properties properties, Map<String, Object> map);
}
/**
* Strategy interface used to test if properties match.
*/
@ -301,9 +301,9 @@ public abstract class YamlProcessor {
* @return the status of the match.
*/
MatchStatus matches(Properties properties);
}
/**
* Status returned from {@link DocumentMatcher#matches(java.util.Properties)}
*/
@ -332,6 +332,7 @@ public abstract class YamlProcessor {
}
}
/**
* Method to use for resolving resources.
*/

View File

@ -20,6 +20,7 @@ import java.util.Map;
import java.util.Properties;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
/**
* Factory for Java Properties that reads from a YAML source. YAML is a nice
@ -57,7 +58,7 @@ import org.springframework.beans.factory.FactoryBean;
* - foo.bar.com
* </pre>
*
* becomes java Properties like this:
* becomes Java Properties like this:
*
* <pre class="code">
* servers=dev.bar.com,foo.bar.com
@ -65,42 +66,40 @@ import org.springframework.beans.factory.FactoryBean;
* servers[1]=foo.bar.com
* </pre>
*
* Can create a singleton or a new object on each request. Default is
* a singleton.
*
* @author Dave Syer
* @author Stephane Nicoll
* @since 4.1
*/
public class YamlPropertiesFactoryBean extends YamlProcessor implements
FactoryBean<Properties> {
public class YamlPropertiesFactoryBean extends YamlProcessor implements FactoryBean<Properties>, InitializingBean {
private boolean singleton = true;
private Properties singletonInstance;
private Properties properties;
/**
* Set whether a shared 'singleton' Properties instance should be
* created, or rather a new Properties instance on each request.
* <p>Default is "true" (a shared singleton).
* Set if a singleton should be created, or a new object on each request
* otherwise. Default is {@code true} (a singleton).
*/
public final void setSingleton(boolean singleton) {
public void setSingleton(boolean singleton) {
this.singleton = singleton;
}
@Override
public final boolean isSingleton() {
public boolean isSingleton() {
return this.singleton;
}
@Override
public void afterPropertiesSet() {
if (isSingleton()) {
this.properties = createProperties();
}
}
@Override
public final Properties getObject() {
if (!this.singleton || this.singletonInstance == null) {
this.singletonInstance = createProperties();
}
return this.singletonInstance;
public Properties getObject() {
return (this.properties != null ? this.properties : createProperties());
}
@Override

View File

@ -22,10 +22,10 @@ import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.annotation.DefaultOrderProviderComparator;
/**
* The default {@link Comparator} to use to order dependencies. Extend
* from {@link DefaultOrderProviderComparator} so that the bean factory
* has the ability to provide an {@link org.springframework.core.annotation.OrderProvider}
* that is aware of more bean metadata, if any.
* The default {@link Comparator} to use to order dependencies. Extends from
* {@link DefaultOrderProviderComparator} so that the bean factory has the ability
* to provide an {@link org.springframework.core.annotation.OrderProvider} that
* is aware of more bean metadata, if any.
*
* @author Stephane Nicoll
* @since 4.1
@ -40,19 +40,22 @@ public class DefaultDependencyComparator extends DefaultOrderProviderComparator
*/
public static final DefaultDependencyComparator INSTANCE = new DefaultDependencyComparator();
private final Comparator<Object> comparator;
public DefaultDependencyComparator() {
this.comparator = AnnotationAwareOrderComparator.INSTANCE;
}
public DefaultDependencyComparator(Comparator<Object> comparator) {
this.comparator = comparator;
}
public DefaultDependencyComparator() {
this(AnnotationAwareOrderComparator.INSTANCE);
}
@Override
public int compare(Object o1, Object o2) {
return comparator.compare(o1, o2);
return this.comparator.compare(o1, o2);
}
}

View File

@ -47,21 +47,24 @@ import org.springframework.core.annotation.OrderProvider;
* @author Stephane Nicoll
* @since 4.1
*/
public class FactoryAwareOrderProvider implements OrderProvider {
class FactoryAwareOrderProvider implements OrderProvider {
private final Map<Object, String> instancesToBeanNames;
private final ConfigurableListableBeanFactory beanFactory;
public FactoryAwareOrderProvider(Map<Object, String> instancesToBeanNames,
ConfigurableListableBeanFactory beanFactory) {
this.instancesToBeanNames = instancesToBeanNames;
this.beanFactory = beanFactory;
}
@Override
public Integer getOrder(Object obj) {
Method factoryMethod = getFactoryMethod(instancesToBeanNames.get(obj));
Method factoryMethod = getFactoryMethod(this.instancesToBeanNames.get(obj));
if (factoryMethod != null) {
Order order = AnnotationUtils.getAnnotation(factoryMethod, Order.class);
if (order != null) {

View File

@ -407,7 +407,9 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
if (this.server == null) {
this.server = JmxUtils.locateMBeanServer();
}
register(); // TODO: to be replaced with some ContextRefreshedEvent-like callback
// TODO: to be replaced with some ContextRefreshedEvent-like callback
register();
}
/**
@ -766,22 +768,22 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
protected DynamicMBean adaptMBeanIfPossible(Object bean) throws JMException {
Class<?> targetClass = AopUtils.getTargetClass(bean);
if (targetClass != bean.getClass()) {
Class<Object> ifc = (Class<Object>) JmxUtils.getMXBeanInterface(targetClass);
Class<?> ifc = JmxUtils.getMXBeanInterface(targetClass);
if (ifc != null) {
if (!(ifc.isInstance(bean))) {
if (!ifc.isInstance(bean)) {
throw new NotCompliantMBeanException("Managed bean [" + bean +
"] has a target class with an MXBean interface but does not expose it in the proxy");
}
return new StandardMBean(bean, ifc, true);
return new StandardMBean(bean, ((Class<Object>) ifc), true);
}
else {
ifc = (Class<Object>) JmxUtils.getMBeanInterface(targetClass);
ifc = JmxUtils.getMBeanInterface(targetClass);
if (ifc != null) {
if (!(ifc.isInstance(bean))) {
if (!ifc.isInstance(bean)) {
throw new NotCompliantMBeanException("Managed bean [" + bean +
"] has a target class with an MBean interface but does not expose it in the proxy");
}
return new StandardMBean(bean, ifc);
return new StandardMBean(bean, ((Class<Object>) ifc));
}
}
}

View File

@ -38,6 +38,7 @@ public class DefaultOrderProviderComparator implements OrderProviderComparator {
*/
public static final DefaultOrderProviderComparator INSTANCE = new DefaultOrderProviderComparator();
@Override
public void sortList(List<?> items, OrderProvider orderProvider) {
Collections.sort(items, new OrderProviderAwareComparator(orderProvider));
@ -53,7 +54,7 @@ public class DefaultOrderProviderComparator implements OrderProviderComparator {
private final OrderProvider orderProvider;
private OrderProviderAwareComparator(OrderProvider orderProvider) {
public OrderProviderAwareComparator(OrderProvider orderProvider) {
this.orderProvider = orderProvider;
}

View File

@ -21,8 +21,8 @@ import java.lang.annotation.Annotation;
import org.springframework.util.ClassUtils;
/**
* General utility for determining the order of an object based
* on its type declaration.
* General utility for determining the order of an object based on its type declaration.
* Handles Spring's {@link Order} annotation as well as {@link javax.annotation.Priority}.
*
* @author Stephane Nicoll
* @since 4.1
@ -36,6 +36,7 @@ public abstract class OrderUtils {
private static final boolean priorityPresent =
ClassUtils.isPresent(PRIORITY_ANNOTATION_CLASS_NAME, OrderUtils.class.getClassLoader());
/**
* Return the order on the specified {@code type} or the specified
* default value if none can be found.
@ -56,8 +57,8 @@ public abstract class OrderUtils {
}
/**
* Return the value of the {@code javax.annotation.Priority} annotation set on the
* specified type or {@code null} if none is set.
* Return the value of the {@code javax.annotation.Priority} annotation set
* on the specified type or {@code null} if none is set.
* @param type the type to handle
* @return the priority value if the annotation is set, {@code null} otherwise
*/