2

I have a custom condition class and a Configuration that has a conditional Bean based of my custom condition class(MyCondition). The problem is I need to access another bean from the context to evaluate the condition, however this is failing saying failed to find 1 bean of type "myBean" because "myBean" requires some other config to load first. In total there are 3 separate configs to load, the order didnt matter until I introduced the 3rd configuration class called MyConfiguration. ConfigurationA and ConfigurationB need to have loaded before MyConfiguration loads. The problem is the condition is called before any of the other beans are instantiated, so even though the context call below in MyCondition gets the the bean name "myBean"(myBean is created in ConfigurationB file) it fails as it requires another bean from ConfigurationA.

I have tired multiple combinations of dependsOn, AutoConfigureAfter, but the order is not relevant because Spring inherently trys to load the condition before it instantiates/creates the beans in the defaultBeansMap.

ConfigurationA
ConfigurationB

@Configuration
public class MyConfiguration {

 @Bean
 @Condition(MyCondition.class)
 public MyClass createMyClass() {
    return new MyClass()
 }

}

public class MyCondition implements Condition  {    ​
    ​@Override
  ​  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
   ​  return context.getBeanFactory().getBean("myBean").getName().equals("Artem");
​   }
}

Can conditions only work on properties loaded and not on order of runtime objects(classes) required?

paul_oshea
  • 67
  • 1
  • 11
  • Have you tried to turn `myBean` into a dependency on `MyCondition` trying to force the creation of `myBean` before `MyCondition`? Never tried this in the past but it might be worth the try. – João Dias Aug 19 '21 at 23:33
  • But mycondition is just a class, it's not a bean itself. I did try that too - it didn't work. – paul_oshea Aug 19 '21 at 23:54
  • Yeah you would need to turn it into a `@Component`. – João Dias Aug 20 '21 at 00:00
  • Have you tried @ConditionalOnBean?Force your required bean to be loaded first. – japhy Aug 20 '21 at 03:08
  • I have tried but conditionalOnBean and dependsOn as an annotation to MyCondition. It doesn't work, the problem I see is that Condition.matches is evaluated before any of the beans in the ConditionContext.beanfactory are initialised. So even though they exist in the map the dependency graph hasn't been created and the beans havent been initialised. One strange thing is that MyBean requires another bean(let's call it BeanC) and that is not present in the beanfactory map, even though I have also made that a dependsOn of MyBean... – paul_oshea Aug 20 '21 at 05:57
  • Could you please upload your project to github? – japhy Aug 20 '21 at 09:51

1 Answers1

0

as per -> How to autowire properties bean from Condition

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.

paul_oshea
  • 67
  • 1
  • 11