【问题标题】:Is Spring's @Profile on methods a good practiceSpring的@Profile方法是一个好习惯吗
【发布时间】:2016-12-19 14:38:10
【问题描述】:

我有一个公开休息服务的 Spring Boot Web 应用程序。

我在问自己如何正确管理过滤器上的配置文件。 实际上,我的应用有 2 个配置文件:dev 和 prod(你猜它代表什么......)

在 prod 模式下,我要激活的过滤器比在 dev 模式下要多。

我的过滤器配置类如下:

@Configuration
public class FiltersConfig {

    @Bean
    public FilterRegistrationBean filterRegistrationBean(CompositeFilter compositeFilter){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setFilter(compositeFilter);
        return filterRegistrationBean;
    }

    @Bean
    @Profile("dev")
    public CompositeFilter devCompositeFilter(){
        CompositeFilter compositeFilter = new CompositeFilter();
        List<Filter> filtersList = new ArrayList<>();
        //filtersList.add(filter1());
        compositeFilter.setFilters(filtersList);
        return compositeFilter;
    }


    @Bean
    @Profile("prod")
    public CompositeFilter prodCompositeFilter(){
        CompositeFilter compositeFilter = new CompositeFilter();
        List<Filter> filtersList = new ArrayList<>();
        //filtersList.add(filter1());
        compositeFilter.setFilters(filtersList);
        return compositeFilter;
    }
}

我的问题是:

  • 在方法上添加@Profile 是一种好习惯吗?
  • 有没有办法强制编译器排除使用与当前设置不同的配置文件注释的类、方法等? (我不希望我的生产 jar/war 填充不必要的代码!)
  • spring boot 是否提供了一种更清晰的方式来组织配置文件?

谢谢。

【问题讨论】:

    标签: java spring maven spring-boot spring-profiles


    【解决方案1】:

    在方法上添加@Profile 是一个好习惯吗?

    这是解决这个问题的 spring 方法 - 所以它与 spring 生态系统保持一致

    有没有办法强制编译器排除使用与当前设置不同的配置文件注释的类、方法等? (我不希望我的生产 jar/war 填充不必要的代码!)

    您必须调整构建以排除类 - 另一种方法是使用 id 配置 bean,并使用每个环境的 ID 和配置。类似于to 的方法

    根据我的经验,配置文件更容易

    spring boot 是否提供了一种更清晰的方式来组织配置文件?

    我不知道,除了上面链接中的方法

    【讨论】:

    • 如果我将构建调整为排除类,这意味着我在类而不是方法上设置了@Profile,对吗?因为如果在同一个类上我有两个使用不同配置文件注释的方法,我猜这两种方法都将在 .class 文件中编译,而不管编译时使用的配置文件如何!这正是让我感到困惑的地方。
    • 或者使用某种构建过程过滤 - 我想这会将配置文件概念移到您的构建过程中
    【解决方案2】:

    我认为在不同的包中为不同的环境进行配置会更好。您不想混合配置。 结构可能如下所示:

    config
        - Config1.java
        - Config2.java
        dev
            - WebConfig.java
            - DataConfig.java
        prod
            - WebConfig.java
            - DataConfig.java
    

    【讨论】:

    • 这如何适应 Spring Boot 的生态系统?
    【解决方案3】:

    根据我自己的经验,在任何 Java 代码中使用 @Profile 都不是一个好主意。这就是为什么我认为你必须避免在代码中使用它:

    1. 您始终可以通过使用配置文件来定义像my.feature-for-the-profile.enabled 这样的属性来实现相同的目标。
    2. 配置文件有时会出现分歧,保留每一个不断变化的配置,因为属性让您可以随时随地更好地控制一切。
    3. Spring Boot 具有明确定义的特定于配置文件的外部化属性支持(如 application-prod.yml)。在您的代码库中包含配置文件会使事情变得更加复杂,有时误导
    4. 与更新和重新编译代码相比,您可以更轻松地使用属性进行修改或覆盖。
    5. ProfileCondition(作为@Profile 上的元注释)不是SpringBootCondition,您不能使用/autoconfig 来确定它是否已激活。

    底线:为properties 定义配置文件,而不是为@Configurations 或@Beans。

    如果您真的想为您的生产代码排除测试内容,请查看spring-boot-devtools 的文档,如果您使用 Maven,您可以将所有测试类/资源放在一个单独的模块中,并将其标记为 @ 987654332@ 或为其定义 Maven 配置文件。请注意,同时拥有 Maven 配置文件和 Spring Boot 配置文件可能会令人困惑!

    【讨论】:

    • 我的经历也让我得出了同样的结论。为每个特性定义一个属性而不是使用@Profile 可以使代码更具可读性,并为您在未来混合和匹配特性提供更​​大的灵活性。
    猜你喜欢
    • 2019-07-17
    • 2016-01-03
    • 1970-01-01
    • 2014-12-22
    • 2020-08-25
    • 2015-05-08
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多