Cache key classes implement Comparable and consistently provide a toString representation
Issue: SPR-14017
This commit is contained in:
parent
a8b5ea1c51
commit
54aeb7a5d6
|
@ -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");
|
* 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.
|
||||||
|
@ -586,7 +586,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||||
* Simple wrapper class around a Method. Used as the key when
|
* Simple wrapper class around a Method. Used as the key when
|
||||||
* caching methods, for efficient equals and hashCode comparisons.
|
* caching methods, for efficient equals and hashCode comparisons.
|
||||||
*/
|
*/
|
||||||
private static class MethodCacheKey {
|
private static final class MethodCacheKey implements Comparable<MethodCacheKey> {
|
||||||
|
|
||||||
private final Method method;
|
private final Method method;
|
||||||
|
|
||||||
|
@ -599,17 +599,28 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
if (other == this) {
|
return (this == other || (other instanceof MethodCacheKey &&
|
||||||
return true;
|
this.method == ((MethodCacheKey) other).method));
|
||||||
}
|
|
||||||
MethodCacheKey otherKey = (MethodCacheKey) other;
|
|
||||||
return (this.method == otherKey.method);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return this.hashCode;
|
return this.hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.method.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(MethodCacheKey other) {
|
||||||
|
int result = this.method.getName().compareTo(other.method.getName());
|
||||||
|
if (result == 0) {
|
||||||
|
result = this.method.toString().compareTo(other.method.toString());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||||
CacheableOperation parseCacheableAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, Cacheable cacheable) {
|
CacheableOperation parseCacheableAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, Cacheable cacheable) {
|
||||||
CacheableOperation.Builder builder = new CacheableOperation.Builder();
|
CacheableOperation.Builder builder = new CacheableOperation.Builder();
|
||||||
|
|
||||||
|
builder.setName(ae.toString());
|
||||||
builder.setCacheNames(cacheable.cacheNames());
|
builder.setCacheNames(cacheable.cacheNames());
|
||||||
builder.setCondition(cacheable.condition());
|
builder.setCondition(cacheable.condition());
|
||||||
builder.setUnless(cacheable.unless());
|
builder.setUnless(cacheable.unless());
|
||||||
|
@ -109,7 +110,6 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||||
builder.setCacheManager(cacheable.cacheManager());
|
builder.setCacheManager(cacheable.cacheManager());
|
||||||
builder.setCacheResolver(cacheable.cacheResolver());
|
builder.setCacheResolver(cacheable.cacheResolver());
|
||||||
builder.setSync(cacheable.sync());
|
builder.setSync(cacheable.sync());
|
||||||
builder.setName(ae.toString());
|
|
||||||
|
|
||||||
defaultConfig.applyDefault(builder);
|
defaultConfig.applyDefault(builder);
|
||||||
CacheableOperation op = builder.build();
|
CacheableOperation op = builder.build();
|
||||||
|
@ -121,6 +121,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||||
CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, CacheEvict cacheEvict) {
|
CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, CacheEvict cacheEvict) {
|
||||||
CacheEvictOperation.Builder builder = new CacheEvictOperation.Builder();
|
CacheEvictOperation.Builder builder = new CacheEvictOperation.Builder();
|
||||||
|
|
||||||
|
builder.setName(ae.toString());
|
||||||
builder.setCacheNames(cacheEvict.cacheNames());
|
builder.setCacheNames(cacheEvict.cacheNames());
|
||||||
builder.setCondition(cacheEvict.condition());
|
builder.setCondition(cacheEvict.condition());
|
||||||
builder.setKey(cacheEvict.key());
|
builder.setKey(cacheEvict.key());
|
||||||
|
@ -129,7 +130,6 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||||
builder.setCacheResolver(cacheEvict.cacheResolver());
|
builder.setCacheResolver(cacheEvict.cacheResolver());
|
||||||
builder.setCacheWide(cacheEvict.allEntries());
|
builder.setCacheWide(cacheEvict.allEntries());
|
||||||
builder.setBeforeInvocation(cacheEvict.beforeInvocation());
|
builder.setBeforeInvocation(cacheEvict.beforeInvocation());
|
||||||
builder.setName(ae.toString());
|
|
||||||
|
|
||||||
defaultConfig.applyDefault(builder);
|
defaultConfig.applyDefault(builder);
|
||||||
CacheEvictOperation op = builder.build();
|
CacheEvictOperation op = builder.build();
|
||||||
|
@ -141,6 +141,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||||
CacheOperation parsePutAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, CachePut cachePut) {
|
CacheOperation parsePutAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, CachePut cachePut) {
|
||||||
CachePutOperation.Builder builder = new CachePutOperation.Builder();
|
CachePutOperation.Builder builder = new CachePutOperation.Builder();
|
||||||
|
|
||||||
|
builder.setName(ae.toString());
|
||||||
builder.setCacheNames(cachePut.cacheNames());
|
builder.setCacheNames(cachePut.cacheNames());
|
||||||
builder.setCondition(cachePut.condition());
|
builder.setCondition(cachePut.condition());
|
||||||
builder.setUnless(cachePut.unless());
|
builder.setUnless(cachePut.unless());
|
||||||
|
@ -148,7 +149,6 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||||
builder.setKeyGenerator(cachePut.keyGenerator());
|
builder.setKeyGenerator(cachePut.keyGenerator());
|
||||||
builder.setCacheManager(cachePut.cacheManager());
|
builder.setCacheManager(cachePut.cacheManager());
|
||||||
builder.setCacheResolver(cachePut.cacheResolver());
|
builder.setCacheResolver(cachePut.cacheResolver());
|
||||||
builder.setName(ae.toString());
|
|
||||||
|
|
||||||
defaultConfig.applyDefault(builder);
|
defaultConfig.applyDefault(builder);
|
||||||
CachePutOperation op = builder.build();
|
CachePutOperation op = builder.build();
|
||||||
|
|
|
@ -746,7 +746,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class CacheOperationCacheKey {
|
private static final class CacheOperationCacheKey implements Comparable<CacheOperationCacheKey> {
|
||||||
|
|
||||||
private final CacheOperation cacheOperation;
|
private final CacheOperation cacheOperation;
|
||||||
|
|
||||||
|
@ -774,6 +774,20 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return (this.cacheOperation.hashCode() * 31 + this.methodCacheKey.hashCode());
|
return (this.cacheOperation.hashCode() * 31 + this.methodCacheKey.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.cacheOperation + " on " + this.methodCacheKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(CacheOperationCacheKey other) {
|
||||||
|
int result = this.cacheOperation.getName().compareTo(other.cacheOperation.getName());
|
||||||
|
if (result == 0) {
|
||||||
|
result = this.methodCacheKey.compareTo(other.methodCacheKey);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,13 @@ public class CacheEvictOperation extends CacheOperation {
|
||||||
|
|
||||||
private final boolean beforeInvocation;
|
private final boolean beforeInvocation;
|
||||||
|
|
||||||
|
|
||||||
|
public CacheEvictOperation(CacheEvictOperation.Builder b) {
|
||||||
|
super(b);
|
||||||
|
this.cacheWide = b.cacheWide;
|
||||||
|
this.beforeInvocation = b.beforeInvocation;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isCacheWide() {
|
public boolean isCacheWide() {
|
||||||
return this.cacheWide;
|
return this.cacheWide;
|
||||||
}
|
}
|
||||||
|
@ -37,12 +44,10 @@ public class CacheEvictOperation extends CacheOperation {
|
||||||
return this.beforeInvocation;
|
return this.beforeInvocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CacheEvictOperation(CacheEvictOperation.Builder b) {
|
|
||||||
super(b);
|
|
||||||
this.cacheWide = b.cacheWide;
|
|
||||||
this.beforeInvocation = b.beforeInvocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
public static class Builder extends CacheOperation.Builder {
|
public static class Builder extends CacheOperation.Builder {
|
||||||
|
|
||||||
private boolean cacheWide = false;
|
private boolean cacheWide = false;
|
||||||
|
@ -71,4 +76,5 @@ public class CacheEvictOperation extends CacheOperation {
|
||||||
return new CacheEvictOperation(this);
|
return new CacheEvictOperation(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ public abstract class CacheOperation implements BasicOperation {
|
||||||
|
|
||||||
private final String toString;
|
private final String toString;
|
||||||
|
|
||||||
|
|
||||||
protected CacheOperation(Builder b) {
|
protected CacheOperation(Builder b) {
|
||||||
this.name = b.name;
|
this.name = b.name;
|
||||||
this.cacheNames = b.cacheNames;
|
this.cacheNames = b.cacheNames;
|
||||||
|
@ -59,11 +60,11 @@ public abstract class CacheOperation implements BasicOperation {
|
||||||
this.toString = b.getOperationDescription().toString();
|
this.toString = b.getOperationDescription().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getCacheNames() {
|
public Set<String> getCacheNames() {
|
||||||
return this.cacheNames;
|
return this.cacheNames;
|
||||||
|
@ -96,7 +97,6 @@ public abstract class CacheOperation implements BasicOperation {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation compares the {@code toString()} results.
|
* This implementation compares the {@code toString()} results.
|
||||||
*
|
|
||||||
* @see #toString()
|
* @see #toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -106,7 +106,6 @@ public abstract class CacheOperation implements BasicOperation {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation returns {@code toString()}'s hash code.
|
* This implementation returns {@code toString()}'s hash code.
|
||||||
*
|
|
||||||
* @see #toString()
|
* @see #toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -118,7 +117,6 @@ public abstract class CacheOperation implements BasicOperation {
|
||||||
* Return an identifying description for this cache operation.
|
* Return an identifying description for this cache operation.
|
||||||
* <p>Returned value is produced by calling {@link Builder#getOperationDescription()}
|
* <p>Returned value is produced by calling {@link Builder#getOperationDescription()}
|
||||||
* during object construction. This method is used in {#hashCode} and {#equals}.
|
* during object construction. This method is used in {#hashCode} and {#equals}.
|
||||||
*
|
|
||||||
* @see Builder#getOperationDescription()
|
* @see Builder#getOperationDescription()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -126,6 +124,10 @@ public abstract class CacheOperation implements BasicOperation {
|
||||||
return this.toString;
|
return this.toString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
public abstract static class Builder {
|
public abstract static class Builder {
|
||||||
|
|
||||||
private String name = "";
|
private String name = "";
|
||||||
|
|
|
@ -28,6 +28,7 @@ public class CachePutOperation extends CacheOperation {
|
||||||
|
|
||||||
private final String unless;
|
private final String unless;
|
||||||
|
|
||||||
|
|
||||||
public CachePutOperation(CachePutOperation.Builder b) {
|
public CachePutOperation(CachePutOperation.Builder b) {
|
||||||
super(b);
|
super(b);
|
||||||
this.unless = b.unless;
|
this.unless = b.unless;
|
||||||
|
@ -37,6 +38,10 @@ public class CachePutOperation extends CacheOperation {
|
||||||
return this.unless;
|
return this.unless;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
public static class Builder extends CacheOperation.Builder {
|
public static class Builder extends CacheOperation.Builder {
|
||||||
|
|
||||||
private String unless;
|
private String unless;
|
||||||
|
@ -58,4 +63,5 @@ public class CachePutOperation extends CacheOperation {
|
||||||
return new CachePutOperation(this);
|
return new CachePutOperation(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ public class CacheableOperation extends CacheOperation {
|
||||||
|
|
||||||
private boolean sync;
|
private boolean sync;
|
||||||
|
|
||||||
|
|
||||||
public CacheableOperation(CacheableOperation.Builder b) {
|
public CacheableOperation(CacheableOperation.Builder b) {
|
||||||
super(b);
|
super(b);
|
||||||
this.unless = b.unless;
|
this.unless = b.unless;
|
||||||
|
@ -76,4 +77,5 @@ public class CacheableOperation extends CacheOperation {
|
||||||
return new CacheableOperation(this);
|
return new CacheableOperation(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
* 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.
|
||||||
|
@ -286,7 +286,7 @@ public abstract class AbstractApplicationEventMulticaster
|
||||||
/**
|
/**
|
||||||
* Cache key for ListenerRetrievers, based on event type and source type.
|
* Cache key for ListenerRetrievers, based on event type and source type.
|
||||||
*/
|
*/
|
||||||
private static class ListenerCacheKey {
|
private static final class ListenerCacheKey implements Comparable<ListenerCacheKey> {
|
||||||
|
|
||||||
private final ResolvableType eventType;
|
private final ResolvableType eventType;
|
||||||
|
|
||||||
|
@ -311,6 +311,23 @@ public abstract class AbstractApplicationEventMulticaster
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return (ObjectUtils.nullSafeHashCode(this.eventType) * 29 + ObjectUtils.nullSafeHashCode(this.sourceType));
|
return (ObjectUtils.nullSafeHashCode(this.eventType) * 29 + ObjectUtils.nullSafeHashCode(this.sourceType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ListenerCacheKey [eventType = " + this.eventType + ", sourceType = " + this.sourceType.getName() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(ListenerCacheKey other) {
|
||||||
|
int result = 0;
|
||||||
|
if (this.eventType != null) {
|
||||||
|
result = this.eventType.toString().compareTo(other.eventType.toString());
|
||||||
|
}
|
||||||
|
if (result == 0 && this.sourceType != null) {
|
||||||
|
result = this.sourceType.getName().compareTo(other.sourceType.getName());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ import org.springframework.util.ObjectUtils;
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
* @see CachedExpressionEvaluator
|
* @see CachedExpressionEvaluator
|
||||||
*/
|
*/
|
||||||
public final class AnnotatedElementKey {
|
public final class AnnotatedElementKey implements Comparable<AnnotatedElementKey> {
|
||||||
|
|
||||||
private final AnnotatedElement element;
|
private final AnnotatedElement element;
|
||||||
|
|
||||||
|
@ -66,4 +66,18 @@ public final class AnnotatedElementKey {
|
||||||
return this.element.hashCode() + (this.targetClass != null ? this.targetClass.hashCode() * 29 : 0);
|
return this.element.hashCode() + (this.targetClass != null ? this.targetClass.hashCode() * 29 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.element + (this.targetClass != null ? " on " + this.targetClass : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(AnnotatedElementKey other) {
|
||||||
|
int result = this.element.toString().compareTo(other.element.toString());
|
||||||
|
if (result == 0 && this.targetClass != null) {
|
||||||
|
result = this.targetClass.getName().compareTo(other.targetClass.getName());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
* 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.
|
||||||
|
@ -63,6 +63,7 @@ import org.springframework.jmx.support.JmxUtils;
|
||||||
import org.springframework.jmx.support.ObjectNameManager;
|
import org.springframework.jmx.support.ObjectNameManager;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.aopalliance.intercept.MethodInterceptor} that routes calls to an
|
* {@link org.aopalliance.intercept.MethodInterceptor} that routes calls to an
|
||||||
|
@ -609,7 +610,7 @@ public class MBeanClientInterceptor
|
||||||
* Simple wrapper class around a method name and its signature.
|
* Simple wrapper class around a method name and its signature.
|
||||||
* Used as the key when caching methods.
|
* Used as the key when caching methods.
|
||||||
*/
|
*/
|
||||||
private static class MethodCacheKey {
|
private static final class MethodCacheKey implements Comparable<MethodCacheKey> {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
|
@ -628,7 +629,7 @@ public class MBeanClientInterceptor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
if (other == this) {
|
if (this == other) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
MethodCacheKey otherKey = (MethodCacheKey) other;
|
MethodCacheKey otherKey = (MethodCacheKey) other;
|
||||||
|
@ -639,6 +640,32 @@ public class MBeanClientInterceptor
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return this.name.hashCode();
|
return this.name.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.name + "(" + StringUtils.arrayToCommaDelimitedString(this.parameterTypes) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(MethodCacheKey other) {
|
||||||
|
int result = this.name.compareTo(other.name);
|
||||||
|
if (result != 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (this.parameterTypes.length < other.parameterTypes.length) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (this.parameterTypes.length > other.parameterTypes.length) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < this.parameterTypes.length; i++) {
|
||||||
|
result = this.parameterTypes[i].getName().compareTo(other.parameterTypes[i].getName());
|
||||||
|
if (result != 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1802,7 +1802,7 @@ public abstract class AnnotationUtils {
|
||||||
/**
|
/**
|
||||||
* Cache key for the AnnotatedElement cache.
|
* Cache key for the AnnotatedElement cache.
|
||||||
*/
|
*/
|
||||||
private static class AnnotationCacheKey {
|
private static final class AnnotationCacheKey implements Comparable<AnnotationCacheKey> {
|
||||||
|
|
||||||
private final AnnotatedElement element;
|
private final AnnotatedElement element;
|
||||||
|
|
||||||
|
@ -1829,6 +1829,20 @@ public abstract class AnnotationUtils {
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return (this.element.hashCode() * 29 + this.annotationType.hashCode());
|
return (this.element.hashCode() * 29 + this.annotationType.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "@" + this.annotationType + " on " + this.element;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(AnnotationCacheKey other) {
|
||||||
|
int result = this.element.toString().compareTo(other.element.toString());
|
||||||
|
if (result == 0) {
|
||||||
|
result = this.annotationType.getName().compareTo(other.annotationType.getName());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -435,7 +435,7 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||||
/**
|
/**
|
||||||
* Key for use with the converter cache.
|
* Key for use with the converter cache.
|
||||||
*/
|
*/
|
||||||
private static final class ConverterCacheKey {
|
private static final class ConverterCacheKey implements Comparable<ConverterCacheKey> {
|
||||||
|
|
||||||
private final TypeDescriptor sourceType;
|
private final TypeDescriptor sourceType;
|
||||||
|
|
||||||
|
@ -470,6 +470,17 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||||
return ("ConverterCacheKey [sourceType = " + this.sourceType +
|
return ("ConverterCacheKey [sourceType = " + this.sourceType +
|
||||||
", targetType = " + this.targetType + "]");
|
", targetType = " + this.targetType + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(ConverterCacheKey other) {
|
||||||
|
int result = this.sourceType.getResolvableType().toString().compareTo(
|
||||||
|
other.sourceType.getResolvableType().toString());
|
||||||
|
if (result == 0) {
|
||||||
|
result = this.targetType.getResolvableType().toString().compareTo(
|
||||||
|
other.targetType.getResolvableType().toString());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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");
|
* 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.
|
||||||
|
@ -33,7 +33,6 @@ import org.springframework.asm.MethodVisitor;
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.core.convert.Property;
|
import org.springframework.core.convert.Property;
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
import org.springframework.core.style.ToStringCreator;
|
|
||||||
import org.springframework.expression.AccessException;
|
import org.springframework.expression.AccessException;
|
||||||
import org.springframework.expression.EvaluationContext;
|
import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.expression.EvaluationException;
|
import org.springframework.expression.EvaluationException;
|
||||||
|
@ -70,11 +69,14 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private final Map<CacheKey, InvokerPair> readerCache = new ConcurrentHashMap<CacheKey, InvokerPair>(64);
|
private final Map<PropertyCacheKey, InvokerPair> readerCache =
|
||||||
|
new ConcurrentHashMap<PropertyCacheKey, InvokerPair>(64);
|
||||||
|
|
||||||
private final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>(64);
|
private final Map<PropertyCacheKey, Member> writerCache =
|
||||||
|
new ConcurrentHashMap<PropertyCacheKey, Member>(64);
|
||||||
|
|
||||||
private final Map<CacheKey, TypeDescriptor> typeDescriptorCache = new ConcurrentHashMap<CacheKey, TypeDescriptor>(64);
|
private final Map<PropertyCacheKey, TypeDescriptor> typeDescriptorCache =
|
||||||
|
new ConcurrentHashMap<PropertyCacheKey, TypeDescriptor>(64);
|
||||||
|
|
||||||
private InvokerPair lastReadInvokerPair;
|
private InvokerPair lastReadInvokerPair;
|
||||||
|
|
||||||
|
@ -96,7 +98,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
if (type.isArray() && name.equals("length")) {
|
if (type.isArray() && name.equals("length")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
CacheKey cacheKey = new CacheKey(type, name, target instanceof Class);
|
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
|
||||||
if (this.readerCache.containsKey(cacheKey)) {
|
if (this.readerCache.containsKey(cacheKey)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +142,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
return new TypedValue(Array.getLength(target));
|
return new TypedValue(Array.getLength(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
CacheKey cacheKey = new CacheKey(type, name, target instanceof Class);
|
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
|
||||||
InvokerPair invoker = this.readerCache.get(cacheKey);
|
InvokerPair invoker = this.readerCache.get(cacheKey);
|
||||||
lastReadInvokerPair = invoker;
|
lastReadInvokerPair = invoker;
|
||||||
|
|
||||||
|
@ -202,7 +204,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass());
|
Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass());
|
||||||
CacheKey cacheKey = new CacheKey(type, name, target instanceof Class);
|
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
|
||||||
if (this.writerCache.containsKey(cacheKey)) {
|
if (this.writerCache.containsKey(cacheKey)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +246,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
throw new AccessException("Type conversion failure", evaluationException);
|
throw new AccessException("Type conversion failure", evaluationException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CacheKey cacheKey = new CacheKey(type, name, target instanceof Class);
|
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
|
||||||
Member cachedMember = this.writerCache.get(cacheKey);
|
Member cachedMember = this.writerCache.get(cacheKey);
|
||||||
|
|
||||||
if (cachedMember == null || cachedMember instanceof Method) {
|
if (cachedMember == null || cachedMember instanceof Method) {
|
||||||
|
@ -301,7 +303,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
if (type.isArray() && name.equals("length")) {
|
if (type.isArray() && name.equals("length")) {
|
||||||
return TypeDescriptor.valueOf(Integer.TYPE);
|
return TypeDescriptor.valueOf(Integer.TYPE);
|
||||||
}
|
}
|
||||||
CacheKey cacheKey = new CacheKey(type, name, target instanceof Class);
|
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
|
||||||
TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey);
|
TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey);
|
||||||
if (typeDescriptor == null) {
|
if (typeDescriptor == null) {
|
||||||
// attempt to populate the cache entry
|
// attempt to populate the cache entry
|
||||||
|
@ -466,7 +468,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CacheKey cacheKey = new CacheKey(type, name, target instanceof Class);
|
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
|
||||||
InvokerPair invocationTarget = this.readerCache.get(cacheKey);
|
InvokerPair invocationTarget = this.readerCache.get(cacheKey);
|
||||||
|
|
||||||
if (invocationTarget == null || invocationTarget.member instanceof Method) {
|
if (invocationTarget == null || invocationTarget.member instanceof Method) {
|
||||||
|
@ -520,17 +522,17 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class CacheKey {
|
private static final class PropertyCacheKey implements Comparable<PropertyCacheKey> {
|
||||||
|
|
||||||
private final Class<?> clazz;
|
private final Class<?> clazz;
|
||||||
|
|
||||||
private final String name;
|
private final String property;
|
||||||
|
|
||||||
private boolean targetIsClass;
|
private boolean targetIsClass;
|
||||||
|
|
||||||
public CacheKey(Class<?> clazz, String name, boolean targetIsClass) {
|
public PropertyCacheKey(Class<?> clazz, String name, boolean targetIsClass) {
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
this.name = name;
|
this.property = name;
|
||||||
this.targetIsClass = targetIsClass;
|
this.targetIsClass = targetIsClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,23 +541,32 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
if (this == other) {
|
if (this == other) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(other instanceof CacheKey)) {
|
if (!(other instanceof PropertyCacheKey)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CacheKey otherKey = (CacheKey) other;
|
PropertyCacheKey otherKey = (PropertyCacheKey) other;
|
||||||
return (this.clazz.equals(otherKey.clazz) && this.name.equals(otherKey.name) &&
|
return (this.clazz == otherKey.clazz && this.property.equals(otherKey.property) &&
|
||||||
this.targetIsClass == otherKey.targetIsClass);
|
this.targetIsClass == otherKey.targetIsClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return (this.clazz.hashCode() * 29 + this.name.hashCode());
|
return (this.clazz.hashCode() * 29 + this.property.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringCreator(this).append("clazz", this.clazz).append("name",
|
return "CacheKey [clazz=" + this.clazz.getName() + ", property=" + this.property + ", " +
|
||||||
this.name).append("targetIsClass", this.targetIsClass).toString();
|
this.property + ", targetIsClass=" + this.targetIsClass + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(PropertyCacheKey other) {
|
||||||
|
int result = this.clazz.getName().compareTo(other.clazz.getName());
|
||||||
|
if (result == 0) {
|
||||||
|
result = this.property.compareTo(other.property);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
* 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.
|
||||||
|
@ -509,7 +509,7 @@ public class CachingConnectionFactory extends SingleConnectionFactory {
|
||||||
* Simple wrapper class around a Destination reference.
|
* Simple wrapper class around a Destination reference.
|
||||||
* Used as the cache key when caching MessageProducer objects.
|
* Used as the cache key when caching MessageProducer objects.
|
||||||
*/
|
*/
|
||||||
private static class DestinationCacheKey {
|
private static class DestinationCacheKey implements Comparable<DestinationCacheKey> {
|
||||||
|
|
||||||
private final Destination destination;
|
private final Destination destination;
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ public class CachingConnectionFactory extends SingleConnectionFactory {
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
// Effectively checking object equality as well as toString equality.
|
// Effectively checking object equality as well as toString equality.
|
||||||
// On WebSphere MQ, Destination objects do not implement equals...
|
// On WebSphere MQ, Destination objects do not implement equals...
|
||||||
return (other == this || destinationEquals((DestinationCacheKey) other));
|
return (this == other || destinationEquals((DestinationCacheKey) other));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -547,6 +547,16 @@ public class CachingConnectionFactory extends SingleConnectionFactory {
|
||||||
// for equivalent destinations... Thanks a lot, WebSphere MQ!
|
// for equivalent destinations... Thanks a lot, WebSphere MQ!
|
||||||
return this.destination.getClass().hashCode();
|
return this.destination.getClass().hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getDestinationString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(DestinationCacheKey other) {
|
||||||
|
return getDestinationString().compareTo(other.getDestinationString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -584,6 +594,12 @@ public class CachingConnectionFactory extends SingleConnectionFactory {
|
||||||
ObjectUtils.nullSafeEquals(this.subscription, otherKey.subscription) &&
|
ObjectUtils.nullSafeEquals(this.subscription, otherKey.subscription) &&
|
||||||
this.durable == otherKey.durable);
|
this.durable == otherKey.durable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + " [selector=" + this.selector + ", noLocal=" + this.noLocal +
|
||||||
|
", subscription=" + this.subscription + ", durable=" + this.durable + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
* 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.
|
||||||
|
@ -203,7 +203,7 @@ public abstract class AbstractFallbackTransactionAttributeSource implements Tran
|
||||||
/**
|
/**
|
||||||
* Default cache key for the TransactionAttribute cache.
|
* Default cache key for the TransactionAttribute cache.
|
||||||
*/
|
*/
|
||||||
private static class DefaultCacheKey {
|
private static final class DefaultCacheKey implements Comparable<DefaultCacheKey> {
|
||||||
|
|
||||||
private final Method method;
|
private final Method method;
|
||||||
|
|
||||||
|
@ -231,6 +231,23 @@ public abstract class AbstractFallbackTransactionAttributeSource implements Tran
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return this.method.hashCode() + (this.targetClass != null ? this.targetClass.hashCode() * 29 : 0);
|
return this.method.hashCode() + (this.targetClass != null ? this.targetClass.hashCode() * 29 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.method + (this.targetClass != null ? " on " + this.targetClass : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(DefaultCacheKey other) {
|
||||||
|
int result = this.method.getName().compareTo(other.method.getName());
|
||||||
|
if (result == 0) {
|
||||||
|
result = this.method.toString().compareTo(other.method.toString());
|
||||||
|
if (result == 0 && this.targetClass != null) {
|
||||||
|
result = this.targetClass.getName().compareTo(other.targetClass.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue