问题
I'm creating multiple Caffeine caches like:
@Bean
public Cache<String, Customer> customerCache() {
return Caffeine.newBuilder()
.maximumSize(10_000)
// other config settings
.build(..);
}
Now I would like to use something like a @ConfigurationProperties(prefix = "cache.customer")
to set the builder config options.
Where a application property cache.customer.maximum-size: 1000
exists.
Is there something smart I can do to map the @ConfigurationProperties
to the Caffeine builder?
回答1:
You can do something similar to what the boot team has done with DataSourceProperties:
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java
You bind your properties into a property class and then use a method on that properties class to create your builder.
Here is a different example where we are binding both the properties and a data source to the same root:
@Bean
@ConfigurationProperties("datasource.task")
public DataSourceProperties taskDataSourceProperties() {
return new DataSourceProperties();
}
@Bean(name = {"taskDataSource"}, destroyMethod="")
@ConfigurationProperties("datasource.task")
@ConditionalOnMissingBean(name="taskDataSource")
public DataSource taskDataSource() {
return taskDataSourceProperties().initializeDataSourceBuilder().build();
}
回答2:
For future readers here is code I used to use Spring Boot's @ConfigurationProperties
to configure a Caffeine Cache:
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
/**
* Base class for configuration of a Caffeine {@link Cache}
*/
public class CaffeineCacheProperties {
private Integer maximumSize;
// TODO: Add additional properties + getters and setters.
public Integer getMaximumSize() {
return maximumSize;
}
public void setMaximumSize(final Integer maximumSize) {
this.maximumSize = maximumSize;
}
public Caffeine initializeCacheBuilder() {
Caffeine cacheBuilder = Caffeine.newBuilder();
if (maximumSize != null) {
cacheBuilder.maximumSize(maximumSize);
}
// TODO: Configure additional properties.
return cacheBuilder;
}
}
.
import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* The cache {@link Configuration} class.
*/
@Configuration
public class CacheConfig {
@Bean
@ConfigurationProperties("cache.customer")
public CaffeineCacheProperties customerCacheProperties() {
return new CacheProperties();
}
@Bean
public Cache<String, Customer> customerCache() {
return customerCacheProperties().initializeCacheBuilder().build();
}
// TODO: Add other caches.
}
And then add a application property like:
cache.customer.maximum-size: 1000
回答3:
You can use @ConfigurationProperties(prefix = "cache.customer")
on top of your CacheConfig
class (A configurations class) where you can easily bind the application properties to your Cache class by using @EnableConfigurationProperties(CacheConfig.class)
.
So now you can auto wire the CacheConfig class to your Cache class and save it as a private attribute in your cache class. And then you can use that configurations through builder like
@Bean
public Cache<String, Customer> customerCache() {
return Caffeine.newBuilder()
.maximumSize(cacheConfig.getMaximumSize())
// other config settings
.build(..);
}
来源:https://stackoverflow.com/questions/51983637/binding-configurationproperties-to-builder-used-to-create-bean