Spring io @Autowired: пустое конечное поле, возможно, не было инициализировано

Я предполагаю, что здесь довольно простой вопрос -

Есть несколько вариантов вопросов относительно этой ошибки, но ни один из первых 5 результатов не имеет добавленного нюанса Spring.

У меня есть начало REST-ful webapp, написанное в Spring. Я пытаюсь подключить его к базе данных.

У меня есть объект с именем Workspace и я пытаюсь использовать spring инъекцию bean (правильная терминология?), чтобы сохранить экземпляр объекта рабочего пространства

package com.parrit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.parrit.models.Workspace;
import com.parrit.models.WorkspaceRepository;

@RestController
@RequestMapping("/workspace")
public class WorkspaceController {

    @Autowired
    private final WorkspaceRepository repository;

    @RequestMapping(method = RequestMethod.POST)
    void save( @RequestBody String workspaceHTML) {
        Workspace ws = new Workspace();
        ws.setHTML(workspaceHTML);
        repository.save(ws);
    }
}

Моя ошибка указана в переменной репозитория private final WorkspaceRepository repository. Компилятор жалуется, что он не может быть инициализирован, и попытка запустить приложение дает тот же результат.

Как мне получить экземпляр этого объекта репозитория в моем контроллере, чтобы сохранить его на нем?

Ответ 1

Имея @Autowired и final на поле, являются противоречивыми.

Последнее говорит: эта переменная имеет одно и только одно значение и инициализируется во время построения.

Первый говорит: Spring построит объект, оставив это поле как null (его значение по умолчанию). Затем Spring будет использовать отражение для инициализации этого поля с помощью bean типа WorkspaceRepository.

Если вы хотите, чтобы конечные поля были автоматически добавлены, используйте инъекцию конструктора, как и вы, если бы вы сделали инъекцию самостоятельно:

@Autowired
public WorkspaceController(WorkspaceRepository repository) {
    this.repository = repository;
}

Ответ 2

Точно вам нужно предоставить конструктор, который назначает конечное поле

private final WorkspaceRepository repository;

@Autowired
public WorkspaceController(WorkspaceRepository repository){
  this.repository = repository;
}

И Spring сможет выяснить, как инициализировать объект и внедрить репозиторий через конструктор