0

I create a bean in configuration class like below:

In FoodConfig.java

@Bean
@Lazy
@Scope("prototype")
public FoodService foodservice(String item, String count){...}

In the FoodService class, I need access to FoodConfig. So I autowired FoodConfig.

abstract class AbstractFoodService{
    @Autowired
    FoodConfig foodConfig;
    String someParam;

    public AbstractFoodService(){
         this.someParam = foodConfig.getParam()
    }
}

I get a Nullpointer exception trying to access someParam in AbstractFoodService class from my FoodServiceTest class.

However, if I inject FoodConfig in constructor of AbstractFoodServiceClass it works.

This works

 public AbstractFoodService(FoodConfig foodConfig){
             this.someParam = foodConfig.getParam();
 }

Can't I autowire other dependencies in a bean that is created using Java configuration?

Thanks, Sudha

user3261334
  • 139
  • 4
  • 13

2 Answers2

1

In first case you are using autowiring through setter injection using @Autowired annotation. As setter injection be done after object creation, so you won't be able to access that. NullPointer is thrown because you're accessing the FoodConfig within default constructor but at that time FoodConfig is not injected.

If you want to use the setter injection rather than constructor one then you won't be able to access them within the constructor. You can access that within methods.

Setter Injection

abstract class AbstractFoodService{
    @Autowired
    FoodConfig foodConfig;    //Setter Injection 
    String someParam;

    public AbstractFoodService(){
         this.someParam = foodConfig.getParam()  //foodConfig is null due to setter injection
    }
}

Constructor injection

public AbstractFoodService(FoodConfig foodConfig){
             this.someParam = foodConfig.getParam();
 }
Gaurav Srivastav
  • 2,381
  • 1
  • 15
  • 18
0

Absolutely right answer by @Gaurav Srivastav.

I am adding some extra points about Setter Injection and Constructor Injection:

We usually advise people to use constructor injection for all mandatory collaborators and setter injection for all other properties. Again, constructor injection ensures all mandatory properties have been satisfied, and it is simply not possible to instantiate an object in an invalid state (not having passed its collaborators). In other words, when using constructor injection you do not have to use a dedicated mechanism to ensure required properties are set (other than normal Java mechanisms).

And Also,

When using Constructor Injection, all required dependencies should be provided through the constructor, as there should not be any setter, to inject them later on. So the instance has all required dependencies! With Setter Injection, the create instance might be there, but without all the required dependencies (as they have not been set through the setter). A user can use the object without setting the required dependencies.

More info view this and this questions.

Thanks :)

Md. Sajedul Karim
  • 6,749
  • 3
  • 61
  • 87