New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make @ConditionalOnBean with multiple beans an AND rather than an OR #5279

Closed
wilkinsona opened this Issue Feb 29, 2016 · 10 comments

Comments

Projects
None yet
5 participants
@wilkinsona
Copy link
Member

wilkinsona commented Feb 29, 2016

No description provided.

@philwebb

This comment has been minimized.

Copy link
Member

philwebb commented Feb 29, 2016

Probably a 2.0 change and one that I'm not too keen on since it could break code in a very subtle way.

@wilkinsona

This comment has been minimized.

Copy link
Member

wilkinsona commented Feb 29, 2016

I thought you'd say that :)

@derTobsch

This comment has been minimized.

Copy link

derTobsch commented Jan 27, 2017

I would be nice if we get a AND with 2.0. :-) I have the case that I want to expose a bean, when two other beans are on the bean factory. Now I got a workaround with one @ConditionalOnBean annotation on the method and one at class level.

Could it be an idea to provide an annotation attribute to switch between "or" and "and" and the default would still be "or" so nothing would break?

@philwebb

This comment has been minimized.

Copy link
Member

philwebb commented Jan 27, 2017

@derTobsch Have you seen the AllNestedConditions, AnyNestedCondition and NoneNestedConditions classes? You can use those to combine conditions together.

@derTobsch

This comment has been minimized.

Copy link

derTobsch commented Jan 28, 2017

@philwebb that's a good reminder. I knew them but barely use them. I give them a try, that should work just fine. thanks

@derTobsch

This comment has been minimized.

Copy link

derTobsch commented Jan 28, 2017

I tried it and it does work but it feels a little bit cumbersome :-)

Here the code for other users finding this issue. I want that both beans are already in the bean factory before running this auto configuration. So i created a inner class and added @Conditional(ConditionOnSecurityAndDiscovery.class) on my auto configuration class.

    static class ConditionOnSecurityAndDiscovery extends AllNestedConditions {

        ConditionOnSecurityAndDiscovery() {

            super(ConfigurationPhase.REGISTER_BEAN);
        }

        @ConditionalOnBean(CoffeeNetAppService.class)
        static class OnDiscovery {
        }

        @ConditionalOnBean(CoffeeNetCurrentUserService.class)
        static class OnSecurity {
        }
    }

examples here e.g. https://github.com/spring-projects/spring-boot/blob/8470ecb4d05c2bcaadd9c58cc7564d7687ae02cd/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hazelcast/HazelcastJpaDependencyAutoConfiguration.java

I must say, that I would prefer something like this below in in the 2.0 version

@ConditionalOnBean(classes = {CoffeeNetAppService.class, CoffeeNetCurrentUserService.class}, operation = Operation.AND)

Thanks for your help @philwebb

@philwebb philwebb added this to the 2.0.0.M1 milestone Feb 2, 2017

@wilkinsona wilkinsona changed the title Consider making @ConditionalOnBean with multiple beans an AND rather than an OR Make @ConditionalOnBean with multiple beans an AND rather than an OR Feb 2, 2017

@wilkinsona wilkinsona self-assigned this Feb 3, 2017

@wilkinsona wilkinsona closed this in 457d041 Feb 6, 2017

@alwaysastudent

This comment has been minimized.

Copy link

alwaysastudent commented Mar 6, 2017

I have been relying on the OR functionality of ConditionalOnBean. Is it possible that original feature be made possible within the ConditionalOnBean annotation itself @derTobsch has been suggesting.

@ConditionalOnBean(classes = {Bean1.class, Bean2.class}, operation = Operation.OR)

Resorting to write AnyNestedCondition for each of the original OR functions would be cumbersome indeed.

@wilkinsona

This comment has been minimized.

Copy link
Member

wilkinsona commented Mar 6, 2017

We discussed the possibility of adding an attribute and decided that it exposed complexity to everyone that was only of use in edge cases so we decided against doing so. Sorry, but we're not going to change that unless a compelling use case that isn't an edge case is brought to our attention.

If you're comfortable with writing the more sophisticated injection logic required by an OR (using an ObjectProvider or @Autowired(required=false), for example) then you'll also need to use AnyNestedCondition.

@heruan

This comment has been minimized.

Copy link

heruan commented Sep 19, 2017

I'm migrating to 2.0.0 and I have a configuration annotated with @ConditionalOnBean({ Foo.class, Bar.class }) which should be evaluated as OR. How can I migrate this to AnyNestedCondition?

@wilkinsona

This comment has been minimized.

Copy link
Member

wilkinsona commented Sep 19, 2017

@heruan Please see this comment above. You'd just use AnyNestedCondition rather than AllNestedCondition. If you have any further questions, please follow up on Stack Overflow or Gitter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment