我可以将 @ConditionalProperty 与我的自定义注释一起使用以避免重复配置吗?
Can I use @ConditionalProperty with my custom annotation to avoid repeating configuration?
我想使用 @OnConditional*family 注释将我的 Spring 启动应用程序的代码从逻辑上划分为几个“功能”。
我发现自己重复了很多代码,例如:
@ConditionalOnProperty( prefix = "pib2.war.features.", value = "hello", matchIfMissing = false )
@RestController
public class HelloController {
...
}
为了便于维护,我想定义元注释,这样我就可以创建某种“功能切换”,例如:
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ConditionalOnProperty( prefix = "pib2.war.features" )
public @interface FeatureToggle {
@AliasFor(annotation = ConditionalOnProperty.class )
String[] value() default { };
@AliasFor(annotation = ConditionalOnProperty.class )
String[] name() default { };
}
这样我的代码就变成了:
@FeatureToggle( "hello" )
@RestController
public class HelloController {
...
}
但这似乎不起作用:OnPropertyCondition
评估代码忽略了 @Aliased
字段,它只是说名称为空:
...
Caused by: java.lang.IllegalStateException: The name or value attribute of @ConditionalOnProperty must be specified
at org.springframework.util.Assert.state(Assert.java:73)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition$Spec.getNames(OnPropertyCondition.java:129)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition$Spec.<init>(OnPropertyCondition.java:122)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition.determineOutcome(OnPropertyCondition.java:88)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition.getMatchOutcome(OnPropertyCondition.java:55)
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
... 90 common frames omitted
所以我想不可能创建这些快捷元注释?我的配置错了吗?我应该编写自己的条件评估程序,例如“OnPropertyCondition”吗?
如果您想编写自己的条件,您应该实施 org.springframework.context.annotation.Condition
这就是 @Profile
通过定义实现 Condition
接口的 ProfileCondition
class 的工作方式:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {
/**
* The set of profiles for which the annotated component should be registered.
*/
String[] value();
}
我想使用 @OnConditional*family 注释将我的 Spring 启动应用程序的代码从逻辑上划分为几个“功能”。
我发现自己重复了很多代码,例如:
@ConditionalOnProperty( prefix = "pib2.war.features.", value = "hello", matchIfMissing = false )
@RestController
public class HelloController {
...
}
为了便于维护,我想定义元注释,这样我就可以创建某种“功能切换”,例如:
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ConditionalOnProperty( prefix = "pib2.war.features" )
public @interface FeatureToggle {
@AliasFor(annotation = ConditionalOnProperty.class )
String[] value() default { };
@AliasFor(annotation = ConditionalOnProperty.class )
String[] name() default { };
}
这样我的代码就变成了:
@FeatureToggle( "hello" )
@RestController
public class HelloController {
...
}
但这似乎不起作用:OnPropertyCondition
评估代码忽略了 @Aliased
字段,它只是说名称为空:
...
Caused by: java.lang.IllegalStateException: The name or value attribute of @ConditionalOnProperty must be specified
at org.springframework.util.Assert.state(Assert.java:73)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition$Spec.getNames(OnPropertyCondition.java:129)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition$Spec.<init>(OnPropertyCondition.java:122)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition.determineOutcome(OnPropertyCondition.java:88)
at org.springframework.boot.autoconfigure.condition.OnPropertyCondition.getMatchOutcome(OnPropertyCondition.java:55)
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
... 90 common frames omitted
所以我想不可能创建这些快捷元注释?我的配置错了吗?我应该编写自己的条件评估程序,例如“OnPropertyCondition”吗?
如果您想编写自己的条件,您应该实施 org.springframework.context.annotation.Condition
这就是 @Profile
通过定义实现 Condition
接口的 ProfileCondition
class 的工作方式:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {
/**
* The set of profiles for which the annotated component should be registered.
*/
String[] value();
}