如何从 Condition 自动装配属性 bean
How to autowire properties bean from Condition
有没有办法在 Condition 中自动装配 bean?
还有下一个例子。我们有 2 个 FileManager 的实现。其中一个实现应该在 属性 'platform' 中初始化。通过 Archaius 处理属性。
@Component
public class AwsPlatformCondition implements Condition {
@Autowired
private ArchaiusProperties archaiusProperties;
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return "aws".equalsIgnoreCase(archaiusProperties.getStringProperty(PropertiesMapper.PLATFORM));
}
}
.
@Component
public class StandardPlatformCondition implements Condition {
@Autowired
private ArchaiusProperties archaiusProperties;
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return "standard".equalsIgnoreCase(archaiusProperties.getStringProperty(PropertiesMapper.PLATFORM));
}
}
.
@Component
@Conditional(AwsPlatformCondition.class)
public class AS3FileManager implements FileManager {
...
}
.
@Component
@Conditional(StandardPlatformCondition.class)
public class NativeFileManager implements FileManager {
...
}
此代码无效。主要原因是 ArchaiusProperties bean 在条件匹配时没有初始化。有没有办法在条件下使用 ArchaiusProperties bean 之前初始化它?
如果我们查看 java docs 的 Condition
界面 -
Conditions must follow the same restrictions as BeanFactoryPostProcessor
and take care to never interact with bean instances.
限制是(从 java docs 到 BeanFactoryPostProcessor
)
A BeanFactoryPostProcessor
may interact with and modify bean definitions, but never bean instances. Doing so may cause premature bean instantiation, violating the container and causing unintended side-effects.
所以您想要实现的是不推荐;已经遇到的副作用。
但是,如果我们在文档中进一步挖掘 Condition
,我们会得到
For more fine-grained control of conditions that interact with @Configuration beans consider the ConfigurationCondition
interface.
这里也违反了限制。因此,总而言之,在这种情况下使用 Condition
并不是一个好主意。
因此,IMO 对您来说最好的选择是使用 @Profile,您可以在其中一次激活所需的配置文件并使用相应的 bean;不考虑附加的装饰。
有没有办法在 Condition 中自动装配 bean?
还有下一个例子。我们有 2 个 FileManager 的实现。其中一个实现应该在 属性 'platform' 中初始化。通过 Archaius 处理属性。
@Component
public class AwsPlatformCondition implements Condition {
@Autowired
private ArchaiusProperties archaiusProperties;
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return "aws".equalsIgnoreCase(archaiusProperties.getStringProperty(PropertiesMapper.PLATFORM));
}
}
.
@Component
public class StandardPlatformCondition implements Condition {
@Autowired
private ArchaiusProperties archaiusProperties;
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return "standard".equalsIgnoreCase(archaiusProperties.getStringProperty(PropertiesMapper.PLATFORM));
}
}
.
@Component
@Conditional(AwsPlatformCondition.class)
public class AS3FileManager implements FileManager {
...
}
.
@Component
@Conditional(StandardPlatformCondition.class)
public class NativeFileManager implements FileManager {
...
}
此代码无效。主要原因是 ArchaiusProperties bean 在条件匹配时没有初始化。有没有办法在条件下使用 ArchaiusProperties bean 之前初始化它?
如果我们查看 java docs 的 Condition
界面 -
Conditions must follow the same restrictions as
BeanFactoryPostProcessor
and take care to never interact with bean instances.
限制是(从 java docs 到 BeanFactoryPostProcessor
)
A
BeanFactoryPostProcessor
may interact with and modify bean definitions, but never bean instances. Doing so may cause premature bean instantiation, violating the container and causing unintended side-effects.
所以您想要实现的是不推荐;已经遇到的副作用。
但是,如果我们在文档中进一步挖掘 Condition
,我们会得到
For more fine-grained control of conditions that interact with @Configuration beans consider the
ConfigurationCondition
interface.
这里也违反了限制。因此,总而言之,在这种情况下使用 Condition
并不是一个好主意。
因此,IMO 对您来说最好的选择是使用 @Profile,您可以在其中一次激活所需的配置文件并使用相应的 bean;不考虑附加的装饰。