Issue
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?
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.
Answered By - Bond - Java Bond
Answer Checked By - Pedro (JavaFixing Volunteer)