NullPointerException 在 Vaadin 和 Spring 中使用 @autowired

NullPointerException using @autowired in Vaadin and Spring

我正在 Vaadin 8 和 Spring 中开发简单的 bookLibrary 项目。我正在努力将服务 class 注入 UI 组件。它一直给我 nullPointerExceptionMessage 。我不使用 "new" 在任何地方创建服务。

这是图书馆服务 class:

 @Service
    public class LibraryService {
    @Autowired
    private BookDao bookDao;
    @Autowired
    private LibraryDao libraryDao;

    private static LibraryService libraryServiceInstance;

    private LibraryService() {

    }

    public static LibraryService getInstance() {
        if (libraryServiceInstance == null) {
            synchronized (LibraryService.class) {
                if (libraryServiceInstance == null) {
                    libraryServiceInstance = new LibraryService();
                }
            }
        }
        return libraryServiceInstance;
    }

    public void saveBook(Book book) {
        libraryDao.findAll().forEach(l -> l.getBooks().add(book));
        book.setLibrary(libraryDao.findOne(1L));
        bookDao.save(book);
    }

    public List<Book> getAllBooks() {
        List<Book> bookList = new ArrayList<>();
        libraryDao.findAll().forEach(l -> l.getBooks().forEach(b -> bookList.add(b)));
        return bookList;
    }

}

GridLayout 看起来像这样:

 @UIScope
    @Component
    public class GridLayout extends CustomComponent {

    @Autowired
    LibraryService libraryService; //this is null

    Grid<Book> bookGrid = new Grid<>(Book.class);
    VerticalLayout verticalLayout = new VerticalLayout();


    public GridLayout(){
        createMainLayout();
        createGrid();
    }

    private void createMainLayout() {
        setCompositionRoot(verticalLayout);
    }

    private void createGrid() {
        bookGrid = new Grid<>(Book.class);
        verticalLayout.addComponent(bookGrid);
        List<Book> books = libraryService.getAllBooks();
        bookGrid.setItems(books);
        bookGrid.removeAllColumns();
        bookGrid.addColumn(Book::getTitle).setCaption("TITLE");
        bookGrid.addColumn(Book::getAuthor).setCaption("AUTHOR");
        bookGrid.addColumn(Book::getYear).setCaption("YEAR");

        verticalLayout.addComponent(bookGrid);
    }
}

主要UI代码在这里:

 @SpringUI
    public class LibraryUI extends UI {
    @Autowired
    private LibraryService libraryService;

    @Autowired
    private BookForm bookForm;

    @Autowired
    private GridLayout gridLayout;

    private HorizontalLayout mainLayout;
    private VerticalLayout verticalLayout = new VerticalLayout();

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        setMainLayout();
        setHeader();
        loadBooks();
        addBookForm();
    }

    public void setMainLayout() {
        mainLayout = new HorizontalLayout();
        setContent(mainLayout);

    }

    public void setHeader() {
        Label header = new Label("Library");
        header.setStyleName(ValoTheme.LABEL_H1);
        verticalLayout.addComponent(header);
        mainLayout.addComponent(verticalLayout);
        verticalLayout.setComponentAlignment(header, Alignment.TOP_CENTER);
        header.addStyleName(ValoTheme.LABEL_H1);
    }

     private void loadBooks(){
        mainLayout.addComponent(gridLayout);
    }

    public void addBookForm() {
        mainLayout.addComponent(bookForm);
        mainLayout.setComponentAlignment(bookForm, Alignment.MIDDLE_CENTER);
    }

如果有任何帮助或想法不对,我将不胜感激。

你可以像

一样注入服务class
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.beans.BeansException;

    @UIScope
    @Component
    public class GridLayout extends CustomComponent implements ApplicationContextAware {

     private static ApplicationContext context;
     private LibraryService libraryService;

             @Override
     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            context = applicationContext;
            libraryService = context.getBean(LibraryService.class);   
           }


                Grid<Book> bookGrid = new Grid<>(Book.class);
                VerticalLayout verticalLayout = new VerticalLayout();


                public GridLayout(){
                    createMainLayout();
                    createGrid();
                }

                private void createMainLayout() {
                    setCompositionRoot(verticalLayout);
                }

                private void createGrid() {
                    bookGrid = new Grid<>(Book.class);
                    verticalLayout.addComponent(bookGrid);
                    List<Book> books = libraryService.getAllBooks();
                    bookGrid.setItems(books);
                    bookGrid.removeAllColumns();
                    bookGrid.addColumn(Book::getTitle).setCaption("TITLE");
                    bookGrid.addColumn(Book::getAuthor).setCaption("AUTHOR");
                    bookGrid.addColumn(Book::getYear).setCaption("YEAR");

                    verticalLayout.addComponent(bookGrid);
                }
            }

问题是您从 GridLayout 构造函数调用 createGrid(),@Autowire 在调用构造函数后注入 bean,所以您需要做的是这样的事情

  public GridLayout(){

}

@PostConstruct
public init(){
    createMainLayout();
    createGrid();
}