ndrone
ndrone

Reputation: 3582

Defining Order of AutoConfigure not working

I have an example project here. In this multi module project. I have module promotion-service on which the PromotionConfiguration relies on other configurations to be completed first.

@Configuration @AutoConfigureAfter({RulesConfiguration.class, PointsConfiguration.class}) public class PromotionConfiguration { @Bean public PromotionService promotionService(ObjectProvider<List<Rule>> rules) { System.out.println("Adding PromotionService to context"); List<Rule> ruleList = rules.getIfAvailable(); if (!ruleList.isEmpty()) { ruleList.sort(Comparator.comparingInt(Rule::getOrder)); } return new PromotionServiceImpl(ruleList); } }

But when the spring boot application that has a dependency of module promotion-service the rules are added to the context after the promotion-service is

2018-02-18 11:20:26.743 INFO 11582 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] Adding PromotionService to context Adding PointRule to context. Adding PromotionRule to context. 2018-02-18 11:20:27.087 INFO 11582 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@196a42c3: startup date [Sun Feb 18 11:20:25 EST 2018]; root of context hierarchy

Upvotes: 0

Views: 944

Answers (1)

Stephane Nicoll
Stephane Nicoll

Reputation: 33101

There is a difference between parsing the configuration and its structure and effectively creating beans at runtime. What is the concrete problem here?

If I run your project, the promotionService is created with 2 rules as you'd expect. If I add @ConditionalOnMissingBean(Rule.class) on promotionService it is not created (which proves the context knows that at least one Rule bean is going to be created).

You shouldn't worry too much about the runtime part, the context is free to invoke the necessary factory methods (i.e. @Bean annotated methods) according to its optimized plan (it namely does smart stuff to resolve cycles).

The reason why you get this log output is that you're not asking the context to resolve the Rule beans. ObjectProvider is a proxy that won't do anything until you ask for something (getAvailable in this case).

I've changed the injection point to use List<Rule> and I got the following:

Adding PointRule to context.
Adding PromotionRule to context.
Adding PromotionService to context

So all is good. But please, rename your auto-configuration so that they ends with AutoConfiguration rather than Configuration.

Upvotes: 2

Related Questions