-1

Autowired class is null in the constructor

I have the following code structure where I am getting null for Autowired Foo class in class Bar. Tried created object of Foo in Bar but then @Autowired Doo becomes null.

@Service
public class Doo{

    public String getString(){
       return "String";
    }
}

@RestController
@Component
@RequestMapping(value = "/do/something", method = RequestMethod.GET)
public class Foo {
    @Autowired 
    private Doo doo;
    // method
    public String getString(){
         return doo.getString();
    }
}

@Component
public final class Bar {
    @Autowired
    Foo foo;

    private static final Bar bar = new Bar();

    private Bar (){
        foo.getString();
    }

    public static Bar getInstance(){
         return bar;
    }
}
  • based on your code, your `Bar` class is not managed by Spring (i.e., it is not a Component or other more specific type) and, therefore, Spring will not be able to inject the dependencies have you tried annotating your class with `@Component`? – andre Jan 06 '20 at 23:48
  • @andre: I apologize, forgot to add `@Component` on Bar class. I have edited the original code. – Kiran Kadam Jan 06 '20 at 23:52
  • @BorisTreukhov: I saw the post you suggested but in that case, Autowired bean is not utilized in the constructor. That makes autowiring bean more difficult. – Kiran Kadam Jan 06 '20 at 23:57
  • have you tried removing the static initialisation? if the class is managed by Spring, it will only be instantiated once and any other class that needs it can use `@Autowire` – andre Jan 06 '20 at 23:59
  • @andre: yes I have tried removing static, but then I am getting "Class cannot be instantiated and does not provide any static methods or fields" PMD violation. – Kiran Kadam Jan 07 '20 at 00:07
  • there is a typo in the Foo class and there is a typo in the Bar class from what I see. – benji2505 Jan 07 '20 at 00:57
  • `return do.getString();` apple should be rather `return doo.getString();` – lczapski Jan 07 '20 at 06:29
  • Autowiring occurs **after** the object has been constructed. So autowired fields aren't available in the constructor. Next to that you are creating an instance yourself, outside the scope of Spring, so that will never have dependencies injected. – M. Deinum Jan 07 '20 at 06:31
  • @benji2505 thanks for pointing out the typos, if we ignore the typos can we focus on the main question which how do I use Autowired bean in the constructor. – Kiran Kadam Jan 07 '20 at 16:40
  • @M.Deinum: I was looking for possible solutions, I found a few solutions. They did not work. Is it that not possible at all to use autowired bean in the constructor? – Kiran Kadam Jan 07 '20 at 16:43
  • Accessing autowired fields will never work because, as stated, injection of those fields happens **after** the object is constructed. If you need the object then use constructor injection instead. – M. Deinum Jan 08 '20 at 06:33

1 Answers1

1

Your code is a bit confusing, since Bar does not do anything.

I tested the following code and it is working:

Foo.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Component
public class Foo {
    @Autowired
    private Doo doo;

    @RequestMapping(value = "/do/something", method = RequestMethod.GET)
    public String getString() {
        return doo.getString();
    }
}

Doo.java

import org.springframework.stereotype.Service;

@Service
public class Doo {

    public String getString() {
        return "String";
    }
}

It is not a best practice to instantiate your controller, since the business logic should go on the Service classes.

As @benji2505 pointed out, there was a few typos on your question also.

I changed the RequestMapping annotation to a method level, you could leave as it was before, but you would also need to add a RequestMapping to the method as per: can anybody explain me difference between class level controller and method level controller..?

andre
  • 448
  • 1
  • 3
  • 8
  • You removed the essential part of the question, in fact, the whole question out of it. The Bar has been autowired somewhere else. I have just put the part related to the question here. Is there any way we can use autowired bean in the contructor ? – Kiran Kadam Jan 07 '20 at 17:53