2017-07-08 10 views
0

我目前正在尝试为Spring和我的Java Web Servlets使用基于Java的新注解配置。我目前在servlet中使用@Autowired注解时遇到了问题,但我不确定它是否是我的配置文件或使用AbstractAnnotationConfigDispatcherServletInitializer引导servlet配置时发生的错误。@Autowire在Java Servlet中使用AbstractAnnotationConfigDispatcherServletInitializer

我已经搜查了论坛,并想我已经找到了答案使用下面的代码片段:

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

但是似乎在调试的“的ServletConfig” - 上下文为null,并导致由于以下错误在被注册到无豆:

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); 
} 

Java配置文件:

public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 

@Override 
protected Class<?>[] getServletConfigClasses() { 
    System.out.println("in Servlet Initializer"); 
    return new Class[] { WebConfig.class }; 
} 

@Override 
protected String[] getServletMappings() { 
    return new String[] { "/" }; 
} 

@Override 
protected Class<?>[] getRootConfigClasses() { 
    return new Class[] { RootConfig.class }; 
} 

}

WebConfig.class:

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

RootConfig.class:

@Configurable 
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(); 
} 

}

谢谢!

回答

1

对于遇到类似的问题的人,我管理我自己的问题感谢解决这个优秀的帖子: getservletconfigclasses-vs-getrootconfigclasses

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

@Configurable 
@ComponentScan({ "com.fdmgroup.bookshop" }) 
public class RootConfig { 
}