user2035039
user2035039

Reputation: 971

Spring 4: NullPointerException during instantiation of ClassPathXmlApplicationContext

I am developing a standalone Spring 4 application, which uses javaFX. However, when I try to create a new ClassPathXmlApplicationContext, all autowired fields are null, leading to NPEs, even though I let Spring instantiate my classes.

This is my main class:

public class Main extends Application {

public static void main(String[] args) {
    launch();
}

public void start(Stage stage) {
    ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    Gui gui = context.getBean(Gui.class);
    stage.setScene(new Scene(gui, 400, 400));
    stage.show();
}
}

This is my spring-config.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-4.2.xsd">

  <context:annotation-config />
  <context:component-scan base-package="org.my.package" />

</beans>

Gui class:

@Controller
@Scope("singleton")
public class Gui extends GridPane {

    @Autowired
    private NetManager netManager;
    @Autowired
    private MessengerComponent messenger;

    public Gui() {
        netManager.init("Username");
            ...
    }
}

NetManager.class:

@Service
@Scope("singleton")
public class NetManager {
    ...
}

The NPE occurs before I even retrieve the first bean, during the creation of the application context. Any idea why?

Upvotes: 1

Views: 131

Answers (1)

J&#233;r&#233;mie B
J&#233;r&#233;mie B

Reputation: 11022

The order of the injection is the following:

  1. Constructor args
  2. Fields
  3. Setters/methods

Under the hood, Spring (or any DI framework) create your class by calling the constructor, and THEN inject the dependencies. So you can't use injected fields in your constructor: they will be injected after.

You should inject the needed dependencies in your constructor:

@Autowired
public Gui(NetManager netManager) {
  this.netManager = netManager;
  netManager.init("Username");
            ...
}

Upvotes: 2

Related Questions