【问题标题】:Spring boot - Service class is nullSpring Boot - 服务类为空
【发布时间】:2016-07-16 21:20:15
【问题描述】:

我正在使用一个在 Spring Boot 应用程序中为 null 的 autoWired 服务类。每个对象都由 Spring 实例化,所以我不知道它为什么会发生。

情况是: 我有一个 Rele.java 类,如下所示:

@Component
public class Rele {

    private Pin pin;
    private GpioController gpio;
    private GpioPinDigitalOutput relePin;
    private static final Logger logger = Logger.getLogger(Rele.class);
    private Interruttore interruttore;
    @Autowired AccensioneService accensioneService;

    public Rele(){

    }

    // Costruttore

    public Rele(Pin pin, Interruttore interruttore) {
        this.pin = pin;
        this.gpio = GpioFactory.getInstance();
        this.relePin = gpio.provisionDigitalOutputPin(pin, "MyRele", PinState.LOW);
        this.interruttore = interruttore;
    }

    public void lightOn() {
        try {

        if (relePin.isLow()) {
            relePin.high();
            updateAccensione(interruttore, true);
            logger.debug("Rele acceso");
        }
        } catch (NullPointerException e) {
            logger.debug("relepin è:" +relePin);
            logger.debug("gpio è:"+gpio);
        }
    }

    public void lightOff() {
        if (relePin.isHigh()) {
            relePin.low();
            updateAccensione(interruttore, false);
            logger.debug("Rele spento");
        }
    }

    public void updateAccensione(Interruttore interruttore, boolean acceso) {

        Date lastDateAccensione = new Date();

        try {
            logger.debug("accensioneService is"+accensioneService);
        lastDateAccensione = accensioneService.findLastDate(interruttore);
        } catch(NullPointerException npe){
            logger.debug("accensioneService is: "+accensioneService);
            logger.error("Error is:", npe);
            lastDateAccensione = new Timestamp(lastDateAccensione.getTime());

        }
        Accensione accensione = new Accensione();
        Date date = new Date();
        logger.debug("lastDate:" + lastDateAccensione);
        accensione.setDateTime(new Timestamp(date.getTime()));
        accensione.setInterruttore(interruttore);
        accensione.setIsLit(acceso);
        accensione.setLastDateTime(lastDateAccensione);
        logger.debug("Accensione è:"+accensione.toString());
        accensioneService.saveAccensione(accensione);

    }

    public Pin getPin() {
        return pin;
    }

    public void setPin(Pin pin) {
        this.pin = pin;
    }

    public Interruttore getInterruttore() {
        return interruttore;
    }

    public void setInterruttore(Interruttore interruttore) {
        this.interruttore = interruttore;
    }

    public GpioPinDigitalOutput getRelePin() {
        return relePin;
    }

    public void setRelePin(GpioPinDigitalOutput relePin) {
        this.relePin = relePin;
    }

    public GpioController getGpio() {
        return gpio;
    }

    public void setGpio(GpioController gpio) {
        this.gpio = gpio;
    }
}

当尝试调用updateAccensione 时,此值为空。 Rele是从Controller中创建的,通过这种方法

@RequestMapping(value="/illuminazione")
    public ResponseEntity<Illuminazione> findIlluminazione(@RequestParam(value="idLuce") int idLuce,
                                                        @RequestParam(value="lit") boolean lit,
                                                        @RequestParam(value="suServer") boolean suServer) {

        Illuminazione illuminazione = new Illuminazione();
        Date lastDate = illuminazioneService.findLastDate(idLuce);
        illuminazione.setLastDateTime(lastDate);
        illuminazione.setIdLuce(idLuce);
        illuminazione.setIsLit(lit);
        Date date = new Date();
        illuminazione.setDateTime(new Timestamp(date.getTime()));
        illuminazioneService.saveIlluminazione(illuminazione);
        logger.debug("Aggiornata luce " + idLuce + " accesa: "+lit);
        //managing rele
        if(suServer){
        //check if status has changed

        Luce luce = luceService.findById(idLuce);
        int idInterruttore = luce.getInterruttore().getIdInterruttore();
        Interruttore interruttore = interruttoreService.findById(idInterruttore);
        Rele rele = releService.findByInterruttore(interruttore);
        logger.debug("rele="+rele.toString());

        if(lit){
        rele.lightOn();
        } else {
        rele.lightOff();
        }

        }

        return new ResponseEntity<Illuminazione>(illuminazione,HttpStatus.OK);

    }

Rele 已创建,我在我的日志中找到它。 AccensioneService 是一个接口,它的具体实现是 AccensioneServiceImpl:

@Service("accensioneService")
@Transactional
public class AccensioneServiceImpl implements AccensioneService{

    @Autowired AccensioneDao dao;

    @Override
    public void saveAccensione(Accensione accensione) {
        dao.saveAccensione(accensione);

    }

    @Override
    public Accensione findById(int id) {

        return dao.findById(id);
    }

    @Override
    public Date findLastDate(Interruttore interruttore) {

        return dao.findLastDate(interruttore);
    }

    @Override
    public boolean findLastStatus(int id) {

        return dao.findLastStatus(id);
    }

    @Override
    public void updateAccensione(Interruttore interruttore) {


    }
}

我不知道是否需要其他任何东西。 AccensioneService 也在其他方法和控制器中被调用,并且它工作......只有在 Rele 内部调用时才会给我这个错误......

【问题讨论】:

  • 您的 releService 似乎正在返回一个非托管 bean。您有多个 Rele 的构造函数这一事实强烈表明您实际上是在创建非托管实例。

标签: java spring


【解决方案1】:

编辑添加

您必须调用new Rele() 或其他Rele(Pin, Interruttore ) 构造函数?如果您在代码中调用这些,accensioneService 将为空,因为 Spring 需要创建 bean,如果您希望将 bean 自动装配到其中或使其能够使用其构造函数创建它是自动装配的。如果你想让它表现得像这样,Spring 必须知道它,所以它必须在(并来自)Spring 上下文中。

在每个构造函数中放置一个日志语句,找出谁在调用它们,并修复它,这样你就可以从 Spring 获取 bean,而不是调用构造函数。

下面的旧答案

您需要发布此方法以确保:

Rele rele = releService.findByInterruttore(interruttore);

我打赌你是通过调用new Rele() 在某处创建rele,这是不正确的。您需要让 Spring 为您创建它。

您没有发布足够的代码来提供进一步的建议。

另外,你说this is null。你在说什么这个

【讨论】:

  • accensioneService为空。当我打电话给Rele rele = releService.findByInterruttore(interruttore); 时,记录器很快就会返回给我这样的信息:rele=it.besmart.parkserver.Rele@b10936...
  • 我看到我正在从另一个类中创建新的 rele,你是对的,现在我有另一个问题,因为我不知道如何从 Spring Boot 中创建 Rele,给他们一个 interruttorepin。只需将 Rele.java 注释为 @Bean?它适用于 Spring Boot 吗?
  • 这是一个单独的问题,但是是的,您应该能够做到这一点。您还可以创建一个支持 Spring 的工厂,它将为您创建 Rele 类并进行注入。有很多方法。如果有,请发布一个新的 SO 问题。
猜你喜欢
  • 1970-01-01
  • 2021-01-31
  • 2022-06-19
  • 2014-07-30
  • 1970-01-01
  • 1970-01-01
  • 2018-08-21
  • 2019-11-24
  • 1970-01-01
相关资源
最近更新 更多