How to autowire properties bean from Condition

autowired, conditional-statements, initialization, java, spring

Solution

If we have a look at java docs for `Condition` interface -

Conditions must follow the same restrictions as `BeanFactoryPostProcessor` and take care to never interact with bean instances.

The restrictions are (from java docs of `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.

So what you are trying to achieve is something not recommended; side effects of which already encountered.

However if we dig further in docs for `Condition` we get

For more fine-grained control of conditions that interact with @Configuration beans consider the `ConfigurationCondition` interface.

Here as well the restrictions are in violation. Thus all in all using `Condition` in this scenario is not a good idea.

So IMO the best bet for you is to go with @Profile where you can activate the desired profile at a time and use the respective bean; without considering the frills attached.

Problem

Does have anyone way to autowire bean in Condition? There is an next example. We have 2 implementation of FileManager. One of implementation should be initialize in depends on property 'platform'. Properties handles via 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 { ... } ``` This code doesn't work. Main reason is because ArchaiusProperties bean doesn't initialized when condition matches. Does have anyone way to initialize ArchaiusProperties bean before using it in condition?

Original source