2

I have

package com.parent.spring;
public abstract class ParentConfig {

@Bean
public String bParent() {
   return "parent bean";
}

then

package com.child.spring;
public class ChildConfig extends ParentConfig {
  @Bean
  public String bChild() {
     return "child bean";
  }
}

and here's how I am starting my spring boot app

@SpringBootApplication
@ComponentScan(basePackages = { "com.child.spring","com.parent.spring" })
public class MyMain {
    public static void main(String args[]) throws Exception {
        SpringApplication.run(MyMain.class, args);
    }
}

I want to load beans from child config first and the from parent config. However, opposite is happening. Don't want to use depends on option as this is just an example, in reality I have lot of beans in child and parent config. Also, I have bunch of other configuration classes in parent package so I don't want to remove that from component scan. Any nicer solution on this ?

Sagar
  • 5,315
  • 6
  • 37
  • 66
  • Have you tried @primary – prasingh Jun 26 '19 at 19:31
  • what is the point of inheriting config ? why cant just the ChildConfig be a separated class that is dependent on the load of the ParentConfig ? and if you need methods and stuff from the ParentConfig , just inject it autowired to the child , and thats it . prefer composition over inheritance https://stackoverflow.com/questions/49002/prefer-composition-over-inheritance – NiNiCkNaMe Jun 26 '19 at 22:11
  • This looks like a gross abuse of inheritance to me - what happens when you you have configurations inheriting from the same parent? Furthermore, of course the parent is loaded first, that's almost exactly how Java inheritance works - the parent ctor is called and completes before the child ctor can be called. Why would you expect using inheritance for configurations to work in the opposite direction? – Boris the Spider Jun 27 '19 at 04:53

2 Answers2

1

I want to load beans from child config first and the from parent config.

You want to explain to the framework how to do its work ?
Spring Configurations and more generally Spring beans are loaded and added in the context in a order that Spring considers the right to satisfy all dependencies requirements.
Besides, configuration inheritance is not documented as a way to achieve such a thing.
Specifying explicitly the order for specific beans is possible but it should be the exception and not the norm while you seem want to do that exception the norm.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
1

Could you please explain more your use case so that we could provide you the best solution we can :) ?

In general its a wrong approach to treat @Configuration files as regular java classes and use all the power of java as a language for the code in this files. You mention inheritance, how about complicated if-conditions, loops, recursion, anyone? :) My point is that you don't really want to end up with complicated code in configuration and to debug it.

Now regarding the inheritance itself. This is not a good idea, because given the fact that its not a regular java class combined with the understanding of how exactly spring uses these configuration files, you'll understand that configuration gives nothing to you here. Think about configurations as a place where you state which beans should be loaded. Spring will take care of the rest. I do understand that you have some use case in mind, but it simply doesn't fit Spring approach.

As for your statement:

I want to load beans from child config first and the from parent config.

Could you please explain why do you need this? When spring loads it scans all the configurations first but doesn't create beans (not yet). Instead it "translates" the information found in these @Configuration classes to a "metadata" (this is called "Bean Definitions" in terms of spring). All the bean definitions from all the configurations....

Only after that Spring starts beans instantiation (it also knows by this time what bean should be created first, for example if you have something like):

class A {
   private B b;
   public A(B b) {this.b = b;}   
 }

class B {
   ....
}

Then its obvious that Spring should create Bean "B" first.

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97