sailor
sailor

Reputation: 781

Spring Boot : order of instantiation

How Spring decided which class to take instantiate first ? Does abstract classes precedes rest ?

public abstract class GenericService {
    @Autowired
    SoaConfig soaConfig;
    public GenericService() {
        System.out.println("----- hi-----"+soaConfig);
    }
}

public class SoaConfig  {
    SoaConfig() {
        System.out.println("\n---- soa config ----");
    }
}

public class SSI extends GenericService {
   public SSI() {
     System.out.println("---- SSI ----");
   }
}

Output is

----- hi-----null
---- SSI ----

---- soa config ----

How i can make, my dependency should always instantiate first ? I tried, @Order(Ordered.HIGHEST_PRECEDENCE), @Priority but no luck yet.

Upvotes: 0

Views: 616

Answers (2)

davidxxx
davidxxx

Reputation: 131396

Abstract classes are not beans in Spring. Only SSI and SoaConfig classes may be beans. So you can only specify the order for them.

Does abstract classes precedes rest ?

Indeed and this doesn't have any relation with Spring. It is a Java concept.
A constructor has to invoke as first statement its parent constructor.
So as SSI is instantiated by Spring, GenericService constructor is first invoked.

About your issue, you have to be aware that for a bean which the class has a no arg constructor, injection on fields or setters occurs after constructor instantiation. So here :

    System.out.println("----- hi-----"+soaConfig);

soaConfig can only be null.

As alternative to @Order or @Priority, you could declare the SoaConfig dependency required as parameter in the constructor. In this way, Spring will inject the SoaConfig bean directly in the constructor invocation.

public abstract class GenericService {   
    SoaConfig soaConfig;
    public GenericService(SoaConfig soaConfig) {
       System.out.println("----- hi-----"+soaConfig);
    }
}

public class SSI extends GenericService {
   public SSI(SoaConfig soaConfig) {
      super(soaConfig);
      System.out.println("---- SSI ----");
   }
}

Upvotes: 2

Adam Zhang
Adam Zhang

Reputation: 96

Try to modify the Autowired object as a parameter for the constructor:

public abstract class GenericService {
    @Autowired
    public GenericService(SoaConfig soaConfig) {
        System.out.println("----- hi-----"+soaConfig);
    }
}

@Configuration
public class SoaConfig  {
    SoaConfig() {
        System.out.println("\n---- soa config ----");
    }
}

@Configuration
public class SSI extends GenericService {
   public SSI(SoapConfig soapConfig) {
     System.out.println("---- SSI ----");
   }
}

Upvotes: 0

Related Questions