Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to autowire properties bean from Condition

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?

like image 956
biven Avatar asked Feb 17 '15 07:02

biven


People also ask

How do I load a spring conditionally bean?

It allows to load beans conditionally depending on a certain environment property: @Configuration @ConditionalOnProperty( value="module. enabled", havingValue = "true", matchIfMissing = true) class CrossCuttingConcernModule { ... } The CrossCuttingConcernModule is only loaded if the module.

What is difference between @bean and @autowire?

@Bean is just for the metadata definition to create the bean(equivalent to tag). @Autowired is to inject the dependancy into a bean(equivalent to ref XML tag/attribute).

What is @conditional annotation in spring?

Introduction. In this tutorial, we'll take a look at the @Conditional annotation. It's used to indicate whether a given component is eligible for registration based on a defined condition.

Can we use @autowired in pojo?

Yes this is possible with the @Configurable annotation and some byte-code magic.


1 Answers

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.

like image 54
Bond - Java Bond Avatar answered Oct 06 '22 00:10

Bond - Java Bond