Rahul
Rahul

Reputation: 183

Constructor injection using Annotations

Why my code is failing with the below error when I AUTOWIRE the no arg constructor but it runs fine when I autowire only the single arg constructor

Exception in thread "main" java.lang.NullPointerException

Here is TennisCoach Class code snippet

@Component // this is bean id 
public class TennisCoach implements Coach {

    public TennisCoach(FortuneService thefortuneservice) {
        System.out.println(" inside 1 arg  constructter");
        fortuneservice = thefortuneservice;
    }


    @Autowired
    public TennisCoach() {
        System.out.println(" inside  0 arg constructter");

    }
}

Coach theCoach = myapp.getBean("tennisCoach", Coach.class);
System.out.println(theCoach.getDailyFortunes());

How are things working behind the scene?

Upvotes: 1

Views: 206

Answers (3)

unlimitednzt
unlimitednzt

Reputation: 1065

Adding to the previous to answers - think about the term "constructor injection". You are INJECTING references via constructor parameters. When you @Autowire an empty constructor, there isn't anything to inject. Therefore you get a NullPointerException when attempting to access the field that was supposed to have a reference injected into.

Upvotes: 0

AhmedRed
AhmedRed

Reputation: 67

Constructor with no arguments doesn't want you put @Autowired on it as you are not injecting anything in its arguments (since there are none). @Autowired is required for constructor with arguments however.

@Component annotation above the class will create your bean via calling the default constructor and you can use that anywhere but need to make sure that you don't call anything on the fortuneservice as that will result in a null ptr exception unless you initialize it. On the contrary, if you put @Autowired annotation on top of constructor with argument and it runs fine then that means that the fortuneservice bean that you have declared elsewhere will now be injected inside this class and no null ptr exception if you call some method on that.

Upvotes: 1

If you have only one constructor in a class, you don't need to use @Autowired--Spring understands that there's only one option, so it uses that one. But you have two constructors, so you need to tell Spring which one to use.

When you invoke the default constructor, however, what do you expect to happen? You don't set up your variables anywhere at all, but you are trying to read from them.

Upvotes: 1

Related Questions