Spring 将@ConfigurationProperties绑定到用于创建bean的生成器

Spring 将@ConfigurationProperties绑定到用于创建bean的生成器,spring,spring-boot,caching,caffeine,Spring,Spring Boot,Caching,Caffeine,我正在创建多个咖啡因缓存,如: @Bean public Cache<String, Customer> customerCache() { return Caffeine.newBuilder() .maximumSize(10_000) // other config settings .build(..); } 现在我想使用@ConfigurationPropertiesprefix=cache.

我正在创建多个咖啡因缓存,如:

@Bean
public Cache<String, Customer> customerCache() {
    return Caffeine.newBuilder()
            .maximumSize(10_000)
            // other config settings
            .build(..);
}
现在我想使用@ConfigurationPropertiesprefix=cache.customer之类的东西来设置生成器配置选项

其中存在应用程序属性cache.customer.max-size:1000

我可以做些聪明的事情来将@ConfigurationProperties映射到Caffee builder吗?

您可以在CacheConfig class A配置类的顶部使用@ConfigurationPropertiesprefix=cache.customer,您可以使用@EnableConfigurationPropertiesCacheConfig.class。 因此,现在可以将CacheConfig类自动关联到缓存类,并将其保存为缓存类中的私有属性。然后,您可以通过类似生成器的方式使用这些配置

@Bean
public Cache<String, Customer> customerCache() {
    return Caffeine.newBuilder()
            .maximumSize(cacheConfig.getMaximumSize())
            // other config settings
            .build(..);
}

您可以执行类似于启动团队对DataSourceProperty所做的操作:

将属性绑定到属性类中,然后使用该属性类上的方法创建生成器

下面是一个不同的示例,其中我们将属性和数据源绑定到同一根:

    @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();
    }

对于未来的读者,这里是我用来使用Spring Boot的@ConfigurationProperties配置咖啡因缓存的代码:

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;
    }
}


问题是我正在创建多个缓存,因此不能在我的CacheConfig类上使用@ConfigurationPropertiesprefix=cache.customer。除此之外,我希望有一个更先进的方法,然后手动设置每个属性。就像Spring Boot的DataSourceBuilder一样。谢谢你的建议。有趣的要求。但我担心的是@ConfigurationProperties不会有帮助,除非您使用不同的前缀,对吗?这意味着每个配置可能有不同的配置类。我不确定spring是否支持除此之外的配置加载应用程序属性的场景。我认为它现在的工作原理是@ConfigurationProperties只是更改该方法返回的bean。就我而言,那太晚了。我正在查看DataSourceBuilder的源代码,但绑定也不起作用。我认为,如果您的配置是预定义的,则可以将所有配置都包含在application.properties文件中,该文件在运行时不会更改,使用不同的前缀应该可以。如果您的配置是在运行时定义的,例如maximumSize将根据逻辑进行更改,那么您可以在CacheConfig文件中更改这些配置,并将其自动连接到构建器。问题是spring在自动连接私有变量之前正在执行构造函数。因此,如果将CacheConfig类自动关联到构建器构造函数,则应用程序应该可以工作。如果我遗漏了什么,请纠正我这正是我要找的。我以前尝试过这个方法,但是忘记了将@Beat注释添加到属性bean中,而属性bean没有被代理。
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.
}
cache.customer.maximum-size: 1000