SpringBoot: how to enable a @Configuration Class only if the corresponding @EnablerAnnotation has been used on a class?

huangapple 未分类评论51阅读模式
英文:

SpringBoot: how to enable a @Configuration Class only if the corresponding @EnablerAnnotation has been used on a class?

问题

怎样才能使一个@Configuration类仅在相应的@EnableCustomConfiguration注解已被使用时才生效?

为了明确,我正在尝试重新创建常见的SpringBoot注解的行为,比如@EnableEurekaClient@EnableWebSecurity等。

这是我的启用器:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableMultitenancy {}

这是我的配置属性:

@Getter
@Setter
@Validated
@ConfigurationProperties("multitenancy")
public class MultitenancyProperties {
    @NotEmpty(message = "You must provide at least one tenant")
    private List<Tenant> tenants;
}

这是我的配置类:

@Configuration
@Conditional("On EnableMultitenancy used")
@EnableConfigurationProperties(MultitenancyProperties.class)
public class MultitenancyConfiguration {
    @Bean
    public MyFirstBean first(MultitenancyProperties properties) {
        return new MyFirstBean(properties);
    }

    @Bean
    public MySecondBean second(MultitenancyProperties properties) {
        return new MySecondBean(properties);
    }
}

我如何编写这样的条件,例如在类/组件上已经使用了该注解?

英文:

How can I enable a @Configuration class only if the corresponding @EnableCustomConfiguration annotation has been used?

To make it clear I am trying to recreate the behaviour of common SpringBoot annotations, like e.g. @EnableEurekaClient, @EnableWebSecurity and so on.

This is my enabler:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableMultitenancy {}

Here my configuration properties:

@Getter
@Setter
@Validated
@ConfigurationProperties(&quot;multitenancy&quot;)
public class MultitenancyProperties {
    @NotEmpty(message = &quot;You must provide at least one tenant&quot;)
    private List&lt;Tenant&gt; tenants;
}

and this is my Configuration class:

@Configuration
@Conditional(&quot;On EnableMultitenancy used&quot;)
@EnableConfigurationProperties(MultitenancyProperties.class)
public class MultitenancyConfiguration{
    @Bean
    public MyFirstBean first(MultitenancyProperties properties){
        return new MyFirstBean(properties);
    }

    @Bean
    public MySecondBean second(MultitenancyProperties properties){
        return new MySecondBean(properties);
    }
}

How can I write such a condition, e.g. the annotation has been used on a class/component?

答案1

得分: 0

org.springframework.context.annotation.ConditionContext 接口展示了 @Conditional 的能力。

ConditionContext 包含五个方法:

  • getRegistry
  • getBeanFactory
  • getEnvironment
  • getResourceLoader
  • getClassLoader

所以看起来你不能直接依赖于注解,例如:@EnableCaching。但你可以依赖于与它们相关的 bean,例如:EnableCaching 的 ProxyCachingConfiguration。

但我认为这不是一个好的设计。通常,我们会声明我们的依赖关系,这使得组件分离,也让事情变得简单。当用户想要使用我们的组件时,他们不需要添加所有依赖的注解,例如:@EnableEureka@EnableWebSecurity,只需@MultitenancyConfiguration

英文:

org.springframework.context.annotation.ConditionContext interface shows theability of @Conditional.

ConditionContext contains five methods:

  • getRegistry
  • getBeanFactory
  • getEnvironment
  • getResourceLoader
  • getClassLoader

So it seems your cannot directly depend on annotation, eg: @EnableCaching. But you can depend on the bean related to them, eg: ProxyCachingConfiguration for EnableCaching.

But i think is not a good design. Usually we will declare our dependency, this makes component sperately, also make things easy. When user want to use our component, they don't need to add all of depended annotation, eg: @EnableEureka,@EnableWebSecurity, just @ MultitenancyConfiguration.

答案2

得分: -1

在你的 MultitenancyConfiguration 类中,你只需要将当前的 @Conditional 注解替换为 @ConditionalOnClass(EnableMulitenancy.class)

更新:抱歉,我误解了。你为什么不直接在你的 EnableMultitenancy 类中使用 @Import(MultitenancyConfiguration.class) 导入 MultitenancyConfiguration 类呢?这将确保在使用 @EnableMultitenancy 时始终启用你的 MultitenancyConfiguration 类。

英文:

In your MultitenancyConfiguration class, you just need to replace the current @Conditional annotation with @ConditionalOnClass(EnableMulitenancy.class).

Update: Sorry, I misunderstood. Why don't you just import the MultitenancyConfiguration class by using @Import(MultitenancyConfiguration.class) in your EnableMultitenancy class? This will guarantee that your MultitenancyConfiguration class is enabled whenever @EnableMultitenancy is used.

huangapple
  • 本文由 发表于 2020年4月7日 02:24:16
  • 转载请务必保留本文链接:https://java.coder-hub.com/61066430.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定