我的应用程序不会以以下消息开头:
应用程序上下文中某些bean的依赖性形成一个循环:
bookController ↓
bookServiceImpl
┌─────┐
bookCommandToBook
↑↓
authorCommandToAuthor
└─────┘
BookController
package pl.springwebapp.webapp.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import pl.springwebapp.webapp.command.BookCommand;
import pl.springwebapp.webapp.service.BookService;
@Slf4j
@Controller
public class BookController {
private BookService bookService;
public BookController(BookService bookService) {
this.bookService = bookService;
}
@RequestMapping("/book/show/{id}")
public String showDescriptionById(@PathVariable long id, Model model){
model.addAttribute("book",bookService.findByID(id));
return "/book/show";
}
@RequestMapping("book/new")
public String newBook(Model model){
model.addAttribute("book", new BookCommand());
return "book/bookform";
}
@PostMapping
@RequestMapping(name = "book")
public String saveOrUpdate(@ModelAttribute BookCommand bookCommand){
bookService.saveBookCommand(bookCommand);
return "redirect:/index";
}
}
BookServiceImpl
package pl.springwebapp.webapp.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import pl.springwebapp.webapp.command.BookCommand;
import pl.springwebapp.webapp.converter.BookCommandToBook;
import pl.springwebapp.webapp.converter.BookToBookCommand;
import pl.springwebapp.webapp.model.Book;
import pl.springwebapp.webapp.repository.BookRepository;
import javax.transaction.Transactional;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
@Slf4j
@Service
public class BookServiceImpl implements BookService {
private BookRepository bookRepository;
private BookCommandToBook bookCommandToBook;
private BookToBookCommand bookToBookCommand;
public BookServiceImpl(BookRepository bookRepository, BookCommandToBook bookCommandToBook, BookToBookCommand bookToBookCommand) {
this.bookRepository = bookRepository;
this.bookCommandToBook = bookCommandToBook;
this.bookToBookCommand = bookToBookCommand;
}
@Override
public Set<Book> getBooks(){
Set<Book> bookSet = new HashSet<>();
bookRepository.findAll().iterator().forEachRemaining(bookSet::add);
return bookSet;
}
@Override
public Book findByID(long id) {
Optional<Book> optionalBook = bookRepository.findById((id));
if(!optionalBook.isPresent()){
throw new RuntimeException("Book not found");
}
return optionalBook.get();
}
@Transactional
@Override
public BookCommand saveBookCommand(BookCommand bookCommand) {
Book receivedBook = bookCommandToBook.convert(bookCommand);
Book savedBook = bookRepository.save(receivedBook);
return bookToBookCommand.convert(savedBook);
}
}
BookCommandToBook
package pl.springwebapp.webapp.converter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import pl.springwebapp.webapp.command.BookCommand;
import pl.springwebapp.webapp.model.Book;
@Component
public class BookCommandToBook implements Converter<BookCommand, Book> {
private AuthorCommandToAuthor authorConverter;
private CategoryCommandToCategory categoryConverter;
public BookCommandToBook(AuthorCommandToAuthor authorConverter, CategoryCommandToCategory categoryConverter) {
this.authorConverter = authorConverter;
this.categoryConverter = categoryConverter;
}
@Override
public Book convert(BookCommand bookCommand) {
Book book = new Book();
book.setId(bookCommand.getId());
book.setTitle(bookCommand.getTitle());
book.setIsbn(bookCommand.getIsbn());
book.setDescription(bookCommand.getDescription());
book.setAuthor(authorConverter.convert(bookCommand.getAuthor()));
if(bookCommand.getCategorySet() != null && bookCommand.getCategorySet().size() > 0 ){
bookCommand.getCategorySet().forEach(categoryCommand -> book.getCategories().add(categoryConverter.convert(categoryCommand)));
}
return book;
}
}
AuthorCommandToAuthor
package pl.springwebapp.webapp.converter;
import lombok.Synchronized;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import pl.springwebapp.webapp.command.AuthorCommand;
import pl.springwebapp.webapp.model.Author;
@Component
public class AuthorCommandToAuthor implements Converter<AuthorCommand, Author> {
private BookCommandToBook bookConverter;
public AuthorCommandToAuthor(BookCommandToBook bookConverter) {
this.bookConverter = bookConverter;
}
@Synchronized
@Override
public Author convert(AuthorCommand authorCommand) {
if(authorCommand==null){
return null;
}
Author author = new Author();
author.setId(authorCommand.getId());
author.setName(authorCommand.getName());
author.setLastName(authorCommand.getLastName());
if(authorCommand.getBookCommandSet() != null && authorCommand.getBookCommandSet().size() > 0){
authorCommand.getBookCommandSet()
.forEach(bookCommand -> author.getBooks().add(bookConverter.convert(bookCommand)));
}
return author;
}
}
AuthorCommand
@Setter
@Getter
@NoArgsConstructor
public class AuthorCommand {
private long id;
private String name;
private String lastName;
private Set<BookCommand> bookCommandSet = new HashSet<>();
}
BookCommand
@Setter
@Getter
@NoArgsConstructor
public class BookCommand {
private long id;
private String title;
private String isbn;
private String description;
private Set<CategoryCommand> categorySet = new HashSet<>();
private AuthorCommand author;
}
您能帮我解决这个问题吗?
答案 0 :(得分:0)
您的应用程序上下文中有一个循环。这意味着一个bean依赖于另一个,反之亦然。 Spring将无法创建那些bean,因为始终必须首先创建一个bean。更具体地说,AuthorCommandToAuthor
需要BookCommandToBook
,而BookCommandToBook
需要AuthorCommandToAuthor
。
要解决您的问题,请将共享代码重构为一个重要的组件,并将其注入两个依赖项中。这样可以消除周期。