Skip to content

Commit b6faaf1

Browse files
committed
Merge branch '5.3.x'
2 parents 73ee87a + de10bb6 commit b6faaf1

File tree

5 files changed

+95
-52
lines changed

5 files changed

+95
-52
lines changed

spring-aspects/src/test/java/org/springframework/cache/aspectj/AspectJEnableCachingIsolatedTests.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
2020
import org.junit.jupiter.api.Disabled;
2121
import org.junit.jupiter.api.Test;
2222

23-
import org.springframework.beans.factory.BeanCreationException;
2423
import org.springframework.cache.CacheManager;
2524
import org.springframework.cache.annotation.CachingConfigurerSupport;
2625
import org.springframework.cache.annotation.EnableCaching;
@@ -107,10 +106,7 @@ public void multipleCachingConfigurers() {
107106
try {
108107
load(MultiCacheManagerConfigurer.class, EnableCachingConfig.class);
109108
}
110-
catch (BeanCreationException ex) {
111-
Throwable root = ex.getRootCause();
112-
boolean condition = root instanceof IllegalStateException;
113-
assertThat(condition).isTrue();
109+
catch (IllegalStateException ex) {
114110
assertThat(ex.getMessage().contains("implementations of CachingConfigurer")).isTrue();
115111
}
116112
}

spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
2020

2121
import org.springframework.beans.factory.config.BeanDefinition;
2222
import org.springframework.cache.annotation.AbstractCachingConfiguration;
23-
import org.springframework.cache.annotation.CachingConfigurer;
2423
import org.springframework.cache.interceptor.CacheResolver;
2524
import org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource;
2625
import org.springframework.cache.jcache.interceptor.JCacheOperationSource;
@@ -46,11 +45,14 @@ public abstract class AbstractJCacheConfiguration extends AbstractCachingConfigu
4645

4746

4847
@Override
49-
protected void useCachingConfigurer(CachingConfigurer config) {
50-
super.useCachingConfigurer(config);
51-
if (config instanceof JCacheConfigurer) {
52-
this.exceptionCacheResolver = ((JCacheConfigurer) config)::exceptionCacheResolver;
53-
}
48+
protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerSupplier) {
49+
super.useCachingConfigurer(cachingConfigurerSupplier);
50+
this.exceptionCacheResolver = cachingConfigurerSupplier.adapt(config -> {
51+
if (config instanceof JCacheConfigurer) {
52+
return ((JCacheConfigurer) config).exceptionCacheResolver();
53+
}
54+
return null;
55+
});
5456
}
5557

5658
@Bean(name = "jCacheOperationSource")

spring-context/src/main/java/org/springframework/cache/annotation/AbstractCachingConfiguration.java

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,9 +16,12 @@
1616

1717
package org.springframework.cache.annotation;
1818

19-
import java.util.Collection;
19+
import java.util.List;
20+
import java.util.function.Function;
2021
import java.util.function.Supplier;
22+
import java.util.stream.Collectors;
2123

24+
import org.springframework.beans.factory.ObjectProvider;
2225
import org.springframework.beans.factory.annotation.Autowired;
2326
import org.springframework.cache.CacheManager;
2427
import org.springframework.cache.interceptor.CacheErrorHandler;
@@ -30,6 +33,7 @@
3033
import org.springframework.core.type.AnnotationMetadata;
3134
import org.springframework.lang.Nullable;
3235
import org.springframework.util.CollectionUtils;
36+
import org.springframework.util.function.SingletonSupplier;
3337

3438
/**
3539
* Abstract base {@code @Configuration} class providing common structure
@@ -70,29 +74,60 @@ public void setImportMetadata(AnnotationMetadata importMetadata) {
7074
}
7175
}
7276

73-
@Autowired(required = false)
74-
void setConfigurers(Collection<CachingConfigurer> configurers) {
75-
if (CollectionUtils.isEmpty(configurers)) {
76-
return;
77-
}
78-
if (configurers.size() > 1) {
79-
throw new IllegalStateException(configurers.size() + " implementations of " +
80-
"CachingConfigurer were found when only 1 was expected. " +
81-
"Refactor the configuration such that CachingConfigurer is " +
82-
"implemented only once or not at all.");
83-
}
84-
CachingConfigurer configurer = configurers.iterator().next();
85-
useCachingConfigurer(configurer);
77+
@Autowired
78+
void setConfigurers(ObjectProvider<CachingConfigurer> configurers) {
79+
Supplier<CachingConfigurer> cachingConfigurer = () -> {
80+
List<CachingConfigurer> candidates = configurers.stream().collect(Collectors.toList());
81+
if (CollectionUtils.isEmpty(candidates)) {
82+
return null;
83+
}
84+
if (candidates.size() > 1) {
85+
throw new IllegalStateException(candidates.size() + " implementations of " +
86+
"CachingConfigurer were found when only 1 was expected. " +
87+
"Refactor the configuration such that CachingConfigurer is " +
88+
"implemented only once or not at all.");
89+
}
90+
return candidates.get(0);
91+
};
92+
useCachingConfigurer(new CachingConfigurerSupplier(cachingConfigurer));
8693
}
8794

8895
/**
8996
* Extract the configuration from the nominated {@link CachingConfigurer}.
9097
*/
91-
protected void useCachingConfigurer(CachingConfigurer config) {
92-
this.cacheManager = config::cacheManager;
93-
this.cacheResolver = config::cacheResolver;
94-
this.keyGenerator = config::keyGenerator;
95-
this.errorHandler = config::errorHandler;
98+
protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerSupplier) {
99+
this.cacheManager = cachingConfigurerSupplier.adapt(CachingConfigurer::cacheManager);
100+
this.cacheResolver = cachingConfigurerSupplier.adapt(CachingConfigurer::cacheResolver);
101+
this.keyGenerator = cachingConfigurerSupplier.adapt(CachingConfigurer::keyGenerator);
102+
this.errorHandler = cachingConfigurerSupplier.adapt(CachingConfigurer::errorHandler);
103+
}
104+
105+
106+
protected static class CachingConfigurerSupplier {
107+
108+
private final Supplier<CachingConfigurer> supplier;
109+
110+
public CachingConfigurerSupplier(Supplier<CachingConfigurer> supplier) {
111+
this.supplier = SingletonSupplier.of(supplier);
112+
}
113+
114+
/**
115+
* Adapt the {@link CachingConfigurer} supplier to another supplier
116+
* provided by the specified mapping function. If the underlying
117+
* {@link CachingConfigurer} is {@code null}, {@code null} is returned
118+
* and the mapping function is not invoked.
119+
* @param provider the provider to use to adapt the supplier
120+
* @param <T> the type of the supplier
121+
* @return another supplier mapped by the specified function
122+
*/
123+
@Nullable
124+
public <T> Supplier<T> adapt(Function<CachingConfigurer, T> provider) {
125+
return () -> {
126+
CachingConfigurer cachingConfigurer = this.supplier.get();
127+
return (cachingConfigurer != null) ? provider.apply(cachingConfigurer) : null;
128+
};
129+
}
130+
96131
}
97132

98133
}

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

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,18 +16,22 @@
1616

1717
package org.springframework.scheduling.annotation;
1818

19-
import java.util.Collection;
19+
import java.util.List;
2020
import java.util.concurrent.Executor;
21+
import java.util.function.Function;
2122
import java.util.function.Supplier;
23+
import java.util.stream.Collectors;
2224

2325
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
26+
import org.springframework.beans.factory.ObjectProvider;
2427
import org.springframework.beans.factory.annotation.Autowired;
2528
import org.springframework.context.annotation.Configuration;
2629
import org.springframework.context.annotation.ImportAware;
2730
import org.springframework.core.annotation.AnnotationAttributes;
2831
import org.springframework.core.type.AnnotationMetadata;
2932
import org.springframework.lang.Nullable;
3033
import org.springframework.util.CollectionUtils;
34+
import org.springframework.util.function.SingletonSupplier;
3135

3236
/**
3337
* Abstract base {@code Configuration} class providing common structure for enabling
@@ -65,17 +69,27 @@ public void setImportMetadata(AnnotationMetadata importMetadata) {
6569
/**
6670
* Collect any {@link AsyncConfigurer} beans through autowiring.
6771
*/
68-
@Autowired(required = false)
69-
void setConfigurers(Collection<AsyncConfigurer> configurers) {
70-
if (CollectionUtils.isEmpty(configurers)) {
71-
return;
72-
}
73-
if (configurers.size() > 1) {
74-
throw new IllegalStateException("Only one AsyncConfigurer may exist");
75-
}
76-
AsyncConfigurer configurer = configurers.iterator().next();
77-
this.executor = configurer::getAsyncExecutor;
78-
this.exceptionHandler = configurer::getAsyncUncaughtExceptionHandler;
72+
@Autowired
73+
void setConfigurers(ObjectProvider<AsyncConfigurer> configurers) {
74+
Supplier<AsyncConfigurer> asyncConfigurer = SingletonSupplier.of(() -> {
75+
List<AsyncConfigurer> candidates = configurers.stream().collect(Collectors.toList());
76+
if (CollectionUtils.isEmpty(candidates)) {
77+
return null;
78+
}
79+
if (candidates.size() > 1) {
80+
throw new IllegalStateException("Only one AsyncConfigurer may exist");
81+
}
82+
return candidates.get(0);
83+
});
84+
this.executor = adapt(asyncConfigurer, AsyncConfigurer::getAsyncExecutor);
85+
this.exceptionHandler = adapt(asyncConfigurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler);
86+
}
87+
88+
private <T> Supplier<T> adapt(Supplier<AsyncConfigurer> supplier, Function<AsyncConfigurer, T> provider) {
89+
return () -> {
90+
AsyncConfigurer asyncConfigurer = supplier.get();
91+
return (asyncConfigurer != null) ? provider.apply(asyncConfigurer) : null;
92+
};
7993
}
8094

8195
}

spring-context/src/test/java/org/springframework/cache/config/EnableCachingTests.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import org.junit.jupiter.api.Test;
2020

21-
import org.springframework.beans.factory.BeanCreationException;
2221
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
2322
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
2423
import org.springframework.cache.CacheManager;
@@ -107,11 +106,8 @@ public void multipleCachingConfigurers() {
107106
try {
108107
ctx.refresh();
109108
}
110-
catch (BeanCreationException ex) {
111-
Throwable root = ex.getRootCause();
112-
boolean condition = root instanceof IllegalStateException;
113-
assertThat(condition).isTrue();
114-
assertThat(root.getMessage().contains("implementations of CachingConfigurer")).isTrue();
109+
catch (IllegalStateException ex) {
110+
assertThat(ex.getMessage().contains("implementations of CachingConfigurer")).isTrue();
115111
}
116112
}
117113

0 commit comments

Comments
 (0)