0

I'm gonna show you all my classes and config file and explain my issue; I keep getting that exception even though I have set up the package to be scanned, also using proper annotations, I even used @Service, @Configuration and the rest of annotations for the services in ProductManager.java and nothing worked, I also checked some other topics in here an none helped me, am I missing something?

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>

Exception thrown

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

EDIT I

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


}

EDIT II

I have change my applicationContext so it scans the package parent and added @Service annotation to SimpleProductManager

NeoChiri
  • 296
  • 4
  • 18

3 Answers3

0

ProductManager is an interface, and you need an implementation of this interface defined in your applicationContext.xml so that it can be created and injected.

See here: Spring interface injection example

Edit

You need to have a bean that implements ProductManager and that is what gets auto-wired as the interface. Think about the difference between an interface and a concrete class - an interface just defines methods, but they do not do anything. First step is to define the class above.

Edit 2

You now have a class implementing ProductManager, but how do you expect Spring to know about it? You say you have annotation scanning on, but your implementation of ProductManager is not annotated nor is it defined in the applicationContext.xml, so how will Spring know it exists?

mikeb
  • 10,578
  • 7
  • 62
  • 120
  • I read that post and I didn't fully understand the difference of Autowiring an interface, in another Spring project I created I did the same thing as here, use @Autowire and set it to be scanned in config files. Is there any written code with annotations that I could take a look to see if I understand what you mean exactly? – NeoChiri Sep 04 '17 at 07:10
  • See my edit - what class do you have that `implements ProductManager`. Until you have that, it's not going to work. – mikeb Sep 05 '17 at 12:30
  • I have a class implementing ProductManager, look at my edit. – NeoChiri Sep 05 '17 at 17:07
  • OK, you're getting there, see my `Edit 2` – mikeb Sep 05 '17 at 20:30
  • See my edit II, I think I did it correctly or I understood something wrong. – NeoChiri Sep 06 '17 at 06:05
  • @NeoChiri still getting same exception ? what about ProductDao bean? – VedantK Sep 06 '17 at 06:26
  • Still getting the very same exception. Nothing about ProductDao. – NeoChiri Sep 06 '17 at 07:14
  • Let's see ProductDao - and make sure you're getting the same exception, not a similar one, the code you have posted seems to be correct so make sure the exception is the same and there is not an error injecting ProductDao or something – mikeb Sep 06 '17 at 12:19
0

You should define a bean that it's type is ProductManager.You can implement the ProductManager,Or create a dynamic proxy object with ProductManager type,and then register it to application context.

dabaicai
  • 999
  • 8
  • 9
0

Your component scan config seems to be wrong. If you have multiple packages to scan You can set root package of them(com.ryc.springapp) or you can use this approach: <context:component-scan base-package="x.y.z.service, x.y.z.controller" /> as explained in here scan-spring-config Of course after adding @Service or @Component annotation to SimpleProductManager class.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Mehmet Sunkur
  • 2,373
  • 16
  • 22