6

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?

biven
  • 132
  • 3
  • 9

2 Answers2

4

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.

Bond - Java Bond
  • 3,972
  • 6
  • 36
  • 59
  • 1
    Thanks! Now I actually think that @Conditional is not a best way for me. – biven Feb 17 '15 at 09:53
  • Setting the profile would depend on the result returned from method in `ArchaiusProperties` bean. How is it possible? Also, doesn't the cited Javadoc say that you actually can refer to beans inside the `ConfigurationCondition`? – X. Wo Satuk Jan 30 '17 at 12:17
0

To get system properties in Condition, I use conditionContext.getEnvironment().getProperty("app.x.y.z", String.class);