|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2002-2020 the original author or authors. |
|
|
|
* Copyright 2002-2021 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. |
|
|
@ -16,9 +16,12 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.cache.annotation; |
|
|
|
package org.springframework.cache.annotation; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.Collection; |
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
import java.util.function.Function; |
|
|
|
import java.util.function.Supplier; |
|
|
|
import java.util.function.Supplier; |
|
|
|
|
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.factory.ObjectProvider; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.cache.CacheManager; |
|
|
|
import org.springframework.cache.CacheManager; |
|
|
|
import org.springframework.cache.interceptor.CacheErrorHandler; |
|
|
|
import org.springframework.cache.interceptor.CacheErrorHandler; |
|
|
@ -30,6 +33,7 @@ import org.springframework.core.annotation.AnnotationAttributes; |
|
|
|
import org.springframework.core.type.AnnotationMetadata; |
|
|
|
import org.springframework.core.type.AnnotationMetadata; |
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
import org.springframework.util.CollectionUtils; |
|
|
|
import org.springframework.util.CollectionUtils; |
|
|
|
|
|
|
|
import org.springframework.util.function.SingletonSupplier; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Abstract base {@code @Configuration} class providing common structure |
|
|
|
* Abstract base {@code @Configuration} class providing common structure |
|
|
@ -70,29 +74,60 @@ public abstract class AbstractCachingConfiguration implements ImportAware { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Autowired(required = false) |
|
|
|
@Autowired |
|
|
|
void setConfigurers(Collection<CachingConfigurer> configurers) { |
|
|
|
void setConfigurers(ObjectProvider<CachingConfigurer> configurers) { |
|
|
|
if (CollectionUtils.isEmpty(configurers)) { |
|
|
|
Supplier<CachingConfigurer> cachingConfigurer = () -> { |
|
|
|
return; |
|
|
|
List<CachingConfigurer> candidates = configurers.stream().collect(Collectors.toList()); |
|
|
|
} |
|
|
|
if (CollectionUtils.isEmpty(candidates)) { |
|
|
|
if (configurers.size() > 1) { |
|
|
|
return null; |
|
|
|
throw new IllegalStateException(configurers.size() + " implementations of " + |
|
|
|
} |
|
|
|
"CachingConfigurer were found when only 1 was expected. " + |
|
|
|
if (candidates.size() > 1) { |
|
|
|
"Refactor the configuration such that CachingConfigurer is " + |
|
|
|
throw new IllegalStateException(candidates.size() + " implementations of " + |
|
|
|
"implemented only once or not at all."); |
|
|
|
"CachingConfigurer were found when only 1 was expected. " + |
|
|
|
} |
|
|
|
"Refactor the configuration such that CachingConfigurer is " + |
|
|
|
CachingConfigurer configurer = configurers.iterator().next(); |
|
|
|
"implemented only once or not at all."); |
|
|
|
useCachingConfigurer(configurer); |
|
|
|
} |
|
|
|
|
|
|
|
return candidates.get(0); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
useCachingConfigurer(new CachingConfigurerSupplier(cachingConfigurer)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Extract the configuration from the nominated {@link CachingConfigurer}. |
|
|
|
* Extract the configuration from the nominated {@link CachingConfigurer}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected void useCachingConfigurer(CachingConfigurer config) { |
|
|
|
protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerSupplier) { |
|
|
|
this.cacheManager = config::cacheManager; |
|
|
|
this.cacheManager = cachingConfigurerSupplier.adapt(CachingConfigurer::cacheManager); |
|
|
|
this.cacheResolver = config::cacheResolver; |
|
|
|
this.cacheResolver = cachingConfigurerSupplier.adapt(CachingConfigurer::cacheResolver); |
|
|
|
this.keyGenerator = config::keyGenerator; |
|
|
|
this.keyGenerator = cachingConfigurerSupplier.adapt(CachingConfigurer::keyGenerator); |
|
|
|
this.errorHandler = config::errorHandler; |
|
|
|
this.errorHandler = cachingConfigurerSupplier.adapt(CachingConfigurer::errorHandler); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected static class CachingConfigurerSupplier { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Supplier<CachingConfigurer> supplier; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public CachingConfigurerSupplier(Supplier<CachingConfigurer> supplier) { |
|
|
|
|
|
|
|
this.supplier = SingletonSupplier.of(supplier); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Adapt the {@link CachingConfigurer} supplier to another supplier |
|
|
|
|
|
|
|
* provided by the specified mapping function. If the underlying |
|
|
|
|
|
|
|
* {@link CachingConfigurer} is {@code null}, {@code null} is returned |
|
|
|
|
|
|
|
* and the mapping function is not invoked. |
|
|
|
|
|
|
|
* @param provider the provider to use to adapt the supplier |
|
|
|
|
|
|
|
* @param <T> the type of the supplier |
|
|
|
|
|
|
|
* @return another supplier mapped by the specified function |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
@Nullable |
|
|
|
|
|
|
|
public <T> Supplier<T> adapt(Function<CachingConfigurer, T> provider) { |
|
|
|
|
|
|
|
return () -> { |
|
|
|
|
|
|
|
CachingConfigurer cachingConfigurer = this.supplier.get(); |
|
|
|
|
|
|
|
return (cachingConfigurer != null) ? provider.apply(cachingConfigurer) : null; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|