Understanding Spring Boot @Autowired

I don’t understand how spring boot’s annotation @Autowired correctly works. Here is a simple example:

@SpringBootApplication
public class App {
    @Autowired
    public Starter starter;

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
    public App() {
        System.out.println("init App");
        //starter.init();
    }
}

@Repository
public class Starter {
    public Starter() {System.out.println("init Starter");}
    public void init() { System.out.println("call init"); }
}

When I execute this code, I get the logs init App and init Starter, so spring creates this objects. But when I call the init method from Starter in App, I get a NullPointerException. Is there more I need to do other than using the annotation @Autowired to init my object?

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'app': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [{package}.App$$EnhancerBySpringCGLIB$$87a7ccf]: Constructor threw exception; nested exception is java.lang.NullPointerException

Answer

When you call the init method from the constructor of class App, Spring has not yet autowired the dependencies into the App object. If you want to call this method after Spring has finished creating and autowiring the App object, then add a method with a @PostConstruct annotation to do this, for example:

@SpringBootApplication
public class App {
    @Autowired
    public Starter starter;

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

    public App() {
        System.out.println("constructor of App");
    }

    @PostConstruct
    public void init() {
        System.out.println("Calling starter.init");
        starter.init();
    }
}

Attribution
Source : Link , Question Author : Community , Answer Author : Jesper

Leave a Comment