@使用AbstractAnnotationConfigDispatcherServletInitializer在java servlet中自动连线

@使用AbstractAnnotationConfigDispatcherServletInitializer在java servlet中自动连线,java,spring,servlets,autowired,spring-annotations,Java,Spring,Servlets,Autowired,Spring Annotations,我目前正在尝试为spring和我的JavaWebservlet使用新的基于Java的注释配置。我目前在servlet本身中使用@Autowired注释时遇到问题,但我不确定这是我的配置文件还是我使用AbstractAnnotationConfigDispatchersServletInitializer引导servlet配置的错误 我搜索了论坛,并认为我已经使用以下代码片段找到了答案: public void init(ServletConfig config) { super.

我目前正在尝试为spring和我的JavaWebservlet使用新的基于Java的注释配置。我目前在servlet本身中使用@Autowired注释时遇到问题,但我不确定这是我的配置文件还是我使用AbstractAnnotationConfigDispatchersServletInitializer引导servlet配置的错误

我搜索了论坛,并认为我已经使用以下代码片段找到了答案:

    public void init(ServletConfig config) {
    super.init(config);
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,config.getServletContext());
  }
但是,在调试时,ServletConfig-context似乎为null,并且由于没有注册bean而导致以下错误:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.fdmgroup.bookshop.service.BookService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.processInjection(AutowiredAnnotationBeanPostProcessor.java:387)
at org.springframework.web.context.support.SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(SpringBeanAutowiringSupport.java:110)
at com.fdmgroup.bookshop.controller.HomeController.init(HomeController.java:46)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1183)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1099)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:779)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:133)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
我目前不确定@ComponentScan是否在我的WebConfig类中被正确激活,ServletConfig上下文是否被正确加载,或者是否有其他东西在起作用。任何帮助都将不胜感激

WebServlet:

@WebServlet("/")
public class HomeController extends HttpServlet {
private static final long serialVersionUID = 1L;

@Autowired
private BookService bookService;

public HomeController() {
}

public HomeController(BookService bookService) {
    this.bookService = bookService;
}

public void init(ServletConfig config) throws ServletException {
    super.init(config);
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,config.getServletContext());
  }


protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    List<Book> books = bookService.retrieveAllBooks();
    request.setAttribute("books", books);
    request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
}
RootConfig.class:

@Configuration
@EnableWebMvc
@ComponentScan({ "com.fdmgroup.bookshop" })
public class WebConfig extends WebMvcConfigurerAdapter {
}
@Configurable
public class RootConfig {
}
@Configurable
@ComponentScan({ "com.fdmgroup.bookshop" })
public class RootConfig {
}
BookService.class:

@Service
public class BookService {
@Autowired
private CRUD<Book> bookRepository;

public BookService(CRUD<Book> bookRepository) {
    this.bookRepository = bookRepository;
}

public BookService() {
}

public void createBook (Book book){
    bookRepository.create(book);
}

public Book retrieveBook (long id){
    return bookRepository.retrieve(id);
}

public void deleteBook (long id){
    bookRepository.delete(id);
}

public List<Book> retrieveAllBooks (){
    return bookRepository.retrieveAll();
}
}


谢谢

对于遇到类似问题的人,我通过这篇优秀的帖子解决了自己的问题:

这个问题确实与@ComponentScan有关,因为我没有意识到WebConfig只扫描Servlet WebApplicationContext中的bean,根WebApplicationContext被完全分开处理。这种新理解的解决方案非常简单,在RootConfig.class中添加了第二个@ComponentScan:

@Configuration
@EnableWebMvc
@ComponentScan({ "com.fdmgroup.bookshop" })
public class WebConfig extends WebMvcConfigurerAdapter {
}
@Configurable
public class RootConfig {
}
@Configurable
@ComponentScan({ "com.fdmgroup.bookshop" })
public class RootConfig {
}