简体   繁体   中英

java.lang.NullPointerException on spring boot

i have created a simple java class in spring boot application. calling a method ns.mesage(); from two different methods but one is executed and another one throw an null pointer exception.

package TestPackage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/*
import TestPackage.MorningService;
import TestPackage.NightService;*/

@RestController
public class GenerateMessage {


    @Autowired
    public MorningService ms;

    @Autowired
    public NightService ns;



    @RequestMapping(path = "/test")
    public String starter(){
        GenerateMessage gm=new GenerateMessage();
        ns.mesage(); // this call working fine

        gm.mes();
        return "Mail scheduled.";
    }




public void mes(){
    try{
    System.out.println("starts2..............");
    ns.mesage(); // throwing an exception
    }catch(Exception e){
        e.printStackTrace();
    }
}
}

Once you're using the new keyword, you're breaking all the injections used with @Autowired (it means that the MorningService and NightService will not be initialized) , that is why you're getting a NPE.

If you really want to test your mes() method from your controller, implement in your @SpringBootApplication class the CommandLineRunner interface.

Then you can inject a GenerateMessage bean with @Autowired and test your method.

Here is an example:

@SpringBootApplication
public class MainApplication implements CommandLineRunner {

 @Autowired
 private GenerateMessage generateMessage;

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

 @Override
 public void run(String... args) throws Exception {
    generateMessage.mes();
 }
}

You must not mix usage of new with Autowired.

Once you're using the new keyword, you're breaking all the injections used with @Autowired(it means that the MorningService and NightService will not be initialized) , that is why you're getting a NPE.

Soulution No.1

use AUTOWIRE

@Autowired
public MorningService ms;

@Autowired
public NightService ns;

@Autowired
GenerateMessage gm;

@RequestMapping(path = "/test")
public String starter(){
//        GenerateMessage gm=new GenerateMessage();
    ns.mesage(); // this call working fine

    gm.mes();
    return "Mail scheduled.";
}

Solution No.2

use this keyword

@RequestMapping(path = "/test")
public String starter(){
//        GenerateMessage gm=new GenerateMessage();
    ns.mesage(); // this call working fine

    this.mes();
    return "Mail scheduled.";
}

When you create an instance with keyword new , it doesn't go through the spring bean lifecycle. In a result post-processor, which response for processing @Autowired annotation doesn't work, and NightService not injected in new instance of GenerateMessage. You just create an instance of the class with null fields.

If you want to create real bean manually you should do it like this:

@RestController
public class GenerateMessage {


    @Autowired
    public MorningService ms;

    @Autowired
    public NightService ns;

    @Autowired
    private ApplicationContext applicationContext;

    @RequestMapping(path = "/test")
    public String starter(){
        GenerateMessage gm=applicationContext.getBean(GenerateMessage.class);
        ns.mesage(); // this call working fine

        gm.mes();
        return "Mail scheduled.";
    }




public void mes(){
    try{
    System.out.println("starts2..............");
    ns.mesage(); // throwing an exception
    }catch(Exception e){
        e.printStackTrace();
    }
}
}

But I do not recommend you to work with the applicationcontext directly, cause it is a heavy object and may lead to decrease performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM