简体   繁体   中英

Autowired dependency when passing data from Controller to Service layer

I am making a Spring web app without any Hibernate/database connection. I merely want to pass data from the Controller layer to the Service that contains the "meat" of the application.

Whenever I try to add the lines:

@Autowired
private CalcArffService calcArffService;

into the controller, an exception is thrown:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [app.service.CalcArffService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

when I try to access all the pages .

How do I solve this?


Here are the necessary files:

CalcController.java

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import app.domain.BreastCancer;
import app.service.CalcArffService;

@Controller
@RequestMapping(value = "calc")
public class CalcController {

  protected final Log logger = LogFactory.getLog(getClass());

  @ModelAttribute("breastCancer")
  public BreastCancer createModel() {
    return new BreastCancer();
  }

  @Autowired
  private CalcArffService calcArffService; // causes trouble tbh

  @RequestMapping(method = RequestMethod.GET)
  public String showCalcPage(ModelMap model) {
    /* stuff */
    return "calc";
  }

  @RequestMapping(method = RequestMethod.POST)
  public String showResultsPage(
      @ModelAttribute("breastCancer") BreastCancer breastCancer,
      BindingResult result) {
    logger.info(breastCancer.toString());
    //calcArffService.evaluate(breastCancer);
    if (result.hasErrors()) {
      return "calc";
    } else {
      return "redirect:calc/results";
    }
  }
}

CalcArffService.java

import app.domain.BreastCancer;

public interface CalcArffService {

  /**
   * 
   * @param breastCancer
   */
  public void evaluate(BreastCancer breastCancer);

}

CalcArffServiceImpl.java

@SuppressWarnings("deprecation")
@Service("calcArffService")
public class CalcArffServiceImpl implements CalcArffService {

  protected final Log logger = LogFactory.getLog(getClass());

  @Autowired
  private CalcArffService calcArffService;

  /**
   * {@inheritDoc}
   */
  @Override
  public void evaluate(BreastCancer breastCancer) {
    logger.info(breastCancer.toString());
  }

}

web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
      id="WebApp_ID" version="2.5">
      <display-name>bosom</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    </web-app>

spring-dispatcher-servlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
      xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

      <context:component-scan base-package="app.controller" />
      <context:component-scan base-package="app.service" />
      <context:component-scan base-package="app.service.impl" />

      <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
          value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
      </bean>

      <!--Enables many annotations and searches for @Controller annotated methods 
        etc.. -->
      <context:annotation-config />

      <!--JSR-303 (Bean validation) support will be detected on classpath and 
        enabled automatically -->
      <mvc:annotation-driven />

      <!--This tag allows for mapping the DispatcherServlet to "/" (all extensions 
        etc) -->
      <mvc:default-servlet-handler />

      <mvc:annotation-driven />
      <mvc:resources location="/css/" mapping="/css/**" />
      <mvc:resources location="/images/" mapping="/images/**" />
      <mvc:resources location="/js/" mapping="/js/**" />

    </beans>

Full stack trace

 SEVERE: Allocate exception for servlet spring
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [app.service.CalcArffService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489)
      at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
      at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
      at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
      at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:599)
      at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
      at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:518)
      at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
      at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
      at javax.servlet.GenericServlet.init(GenericServlet.java:212)
      at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1173)
      at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:809)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:129)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
      at java.lang.Thread.run(Unknown Source)

in your controller add the following

@Autowired
@Qualifier("calcArffService")
private CalcArffService calcArffService; // causes trouble tbh

and it should work. Also add context:component-scan to you spring config to allo annotation scanning.

Setup the component scanner to scan for beans in your service package. In spring-dispatcher-servlet.xml add:

<context:component-scan base-package="app.service" />

In order for dependency injection to work, the component being injected and the component receiving the injection must both be beans. Both the service and the bean must be discovered via component scanning.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM