【问题标题】:Exception autowiring a class in Spring Project在 Spring Project 中自动装配类的异常
【发布时间】:2018-02-12 04:39:55
【问题描述】:

我将向您展示我的所有课程和配置文件并解释我的问题;即使我已经设置了要扫描的包,也使用了正确的注释,我什至使用了@Service、@Configuration 和 ProductManager.java 中服务的其余注释,但没有任何效果,我也检查了一些这里的其他主题对我没有帮助,我错过了什么吗?

ProductManager.java

public interface ProductManager extends Serializable{

    public void increasePrice(int percentage);

    public List<Product> getProducts();
}

InventoryController.java

@Controller
public class InventoryController {

@Autowired
private ProductManager productManager;


@RequestMapping(value="/hello.htm")
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{

    String now = (new Date()).toString();

    Map<String, Object> myModel = new HashMap<String, Object>();
    myModel.put("now", now);
    myModel.put("products", this.productManager.getProducts());

    return new ModelAndView("hello", "model", myModel);
}

public void setProductManager(ProductManager productManager){
    this.productManager = productManager;
}

public ProductManager getProductManager() {
    return productManager;
}
}

app-config.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="messages"/>
</bean>

<!-- Escanea el directorio de la aplicación para encontrar @Components como Beans -->
<context:component-scan base-package="com.ryc.springapp.web"/>

<!-- Configures the @Controller programming model -->
<mvc:annotation-driven/>

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

applicationContext.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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">


<!-- holding properties for database connectivity /-->
<context:property-placeholder location="classpath:jdbc.properties"/>

<!-- enabling annotation driven configuration /-->
<context:annotation-config/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="${jdbc.driverClassName}"/>
  <property name="url" value="${jdbc.url}"/>
  <property name="username"  value="${jdbc.username}"/>
  <property name="password" value="${jdbc.password}"/>
</bean>

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"
p:jpaVendorAdapter-ref="jpaAdapter">
<property name="loadTimeWeaver">
        <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>                             
<property name="persistenceUnitName" value="springappPU"></property>
</bean>

<bean id="jpaAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="${jpa.database}"
p:showSql="${jpa.showSql}"/>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>

<tx:annotation-driven transaction-manager="transactionManager"/>

<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="com.ryc.springapp" />

</beans>

抛出异常

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'inventoryController': Unsatisfied dependency expressed through field 'productManager'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.ryc.springapp.service.ProductManager' 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.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:682)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:553)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:171)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1227)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1140)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1027)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5038)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5348)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3869)
at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:291)
at org.apache.catalina.core.StandardContext.backgroundProcess(StandardContext.java:5671)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1377)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1381)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1381)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1349)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.ryc.springapp.service.ProductManager' 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:1493)
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)
... 33 more

sep 04, 2017 1:04:49 AM org.apache.catalina.core.StandardContext loadOnStartup

编辑我

SimpleProductManager.java

@Service
public class SimpleProductManager implements ProductManager{

private static final long serialVersionUID = 1L;
@Autowired
private ProductDao productDao;

public List<Product> getProducts() {
    return productDao.getProductList();

}

public void increasePrice(int percentage) {
    List<Product> products = productDao.getProductList();
     if(products != null){
         for(Product product : products){
             double newPrice = product.getPrice().doubleValue() * (100 + percentage)/100;
             product.setPrice(newPrice);
             productDao.saveProduct(product);
         }
     } 
}

public ProductDao getProductDao() {
    return productDao;
}

public void setProductDao(ProductDao productDao) {
    this.productDao = productDao;
}


}

编辑二

我已经更改了我的 applicationContext,因此它会扫描父包并将 @Service 注释添加到 SimpleProductManager

【问题讨论】:

  • 你在注入它的实现吗?
  • 修改后您是否仍然面临问题?
  • 是的,我也面临同样的问题。

标签: java spring spring-mvc


【解决方案1】:

你应该定义一个bean,它的类型是ProductManager。你可以实现ProductManager,或者创建一个ProductManager类型的动态代理对象,然后注册到应用上下文中。

【讨论】:

  • 我该怎么做?
【解决方案2】:

ProductManager 是一个接口,您需要在 applicationContext.xml 中定义此接口的实现,以便可以创建和注入。

请看这里: Spring interface injection example

编辑

您需要有一个 implements ProductManager 的 bean,这就是自动连接为接口的东西。想想接口和具体类之间的区别——接口只定义方法,但它们不做任何事情。第一步是定义上面的类。

编辑 2

您现在有一个实现ProductManager 的类,但是您希望Spring 如何知道它?你说你开启了注解扫描,但是ProductManager的实现没有注解也没有在applicationContext.xml中定义,那么Spring怎么知道它存在呢?

【讨论】:

  • 我读了那篇文章,但我并没有完全理解自动装配接口的区别,在我创建的另一个 Spring 项目中,我做了和这里一样的事情,使用 @Autowire 并将其设置为扫描配置文件。是否有任何带有注释的书面代码,我可以看看我是否理解你的意思?
  • 查看我的编辑 - 你有什么课程 implements ProductManager。在你拥有它之前,它是行不通的。
  • 我有一个实现 ProductManager 的类,看看我的编辑。
  • 好的,你到了那里,见我的Edit 2
  • 查看我的编辑 II,我认为我做得正确或理解有误。
【解决方案3】:

您的组件扫描配置似乎有误。如果您有多个要扫描的包您可以设置它们的根包(com.ryc.springapp),或者您可以使用这种方法: 正如这里scan-spring-config中所解释的那样 当然是在SimpleProductManager类中添加@Service或者@Component注解之后。

【讨论】:

    猜你喜欢
    • 2017-11-20
    • 2014-10-07
    • 2017-10-22
    • 2016-09-04
    • 1970-01-01
    • 2020-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    相关资源
    最近更新 更多