@Autowired -不需要至少1个bean的类型的限定bean。

时间:2022-09-11 15:03:08

Currently I'm facing an issue in Autowire configuration between controller and the service layer.

目前,我在控制器和服务层之间的Autowire配置中遇到了一个问题。

I'm unable to trace my mistakes.

我无法找出我的错误。

Simple Log Info

简单的日志信息

    SEVERE:   Exception while loading the app
    SEVERE:   Undeployment failed for context /OTT
    SEVERE:   Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.ott.service.EmployeeService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

Below I have also given the Controller and Service Layer code and also the dispatcher-servlet.xml

下面我还给出了控制器和服务层代码以及dispatcher-servlet.xml。

Controller

控制器

package com.ott.controller;

import com.ott.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

    /**
     *
     * @author SPAR
     */
    @Controller
    public class AdminController {

        private EmployeeService employeeService;

        @RequestMapping("/employee")
        public String employee(){
            this.employeeService.fetchAll();
            return "employee";
        }

        @Autowired(required = true)
        @Qualifier(value="employeeService")
        public void setEmployeeService(EmployeeService empService) {
            this.employeeService = empService;
        }

    }

Service Interface

服务接口

package com.ott.service;

import com.ott.hibernate.Employee;
import java.util.List;

/**
 *
 * @author SPAR
 */
public interface EmployeeService {

     List<Employee> fetchAll();


}

Service Interface Impl

服务接口Impl

package com.ott.service;

import com.ott.dao.EmployeeDAO;
import com.ott.hibernate.Employee;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author SPAR
 */
@Service
public class EmployeeServiceImpl implements EmployeeService{

    private EmployeeDAO employeeDAO;

    @Override
    @Transactional(readOnly = true)
    public List<Employee> fetchAll() {

        List<Employee> employees = employeeDAO.fetchAll();
        for (Employee employee : employees) {

            System.out.println("Name : "+employee.getFirst_Name() +" "+ employee.getLast_Name());

            System.out.println("Email Id : "+employee.getEmail_Id());
        }

        return employees;
    }

    @Autowired(required = true)
    @Qualifier(value="employeeDAO")
    public void setEmployeeDAO(EmployeeDAO empDAO) {
        this.employeeDAO = empDAO;
    }
}

Dispatcher-servlet.xml

Dispatcher-servlet.xml

 <?xml version='1.0' encoding='UTF-8' ?>
    <!-- was: <?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:p="http://www.springframework.org/schema/p"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           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.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

        <context:component-scan base-package="com.ott.controller"/>
        <context:component-scan base-package="com.ott.hibernate"/>
        <context:component-scan base-package="com.ott.service"/>
        <context:component-scan base-package="com.ott.dao"/>

        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

        <mvc:resources mapping="/resources/**" location="/resources/" />

         <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
            <property name="definitions">
                <list>
                    <value>/WEB-INF/tiles-def/general-layout.xml</value>
                </list>
            </property>
        </bean>

        <bean id="viewResolverTiles" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
        </bean> 

        <mvc:annotation-driven />

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

9 个解决方案

#1


4  

You don't have to necessarily provide name and Qualifier. If you set a name, that's the name with which the bean is registered in the context. If you don't provide a name for your service it will be registered as uncapitalized non-qualified class name based on BeanNameGenerator. So in your case the Implementation will be registered as employeeServiceImpl. So if you try to autowire with that name, it should resolve directly.

您不必提供名称和限定符。如果您设置了一个名称,那就是在上下文中注册bean的名称。如果您没有为您的服务提供一个名称,那么它将被注册为基于BeanNameGenerator的未注册的非限定类名。因此,在您的情况下,实现将注册为employeeServiceImpl。因此,如果您尝试使用该名称自动连接,它应该直接解析。

private EmployeeService employeeServiceImpl;

@RequestMapping("/employee")
public String employee() {
    this.employeeService.fetchAll();
    return "employee";
}

@Autowired(required = true)
public void setEmployeeService(EmployeeService employeeServiceImpl) {
    this.employeeServiceImpl = employeeServiceImpl;
}

@Qualifier is used in case if there are more than one bean exists of same type and you want to autowire different implementation beans for various purposes.

如果有多个bean存在相同的类型,并且您想为不同的目的自动连接不同的实现bean,则使用@Qualifier。

#2


5  

Guys I found the issue

伙计们,我发现了这个问题。

I just tried by adding the qualifier name in employee service finally it solved my issue.

我只是在员工服务中添加了qualifier的名字,最终解决了我的问题。

@Service("employeeService")

public class EmployeeServiceImpl implements EmployeeService{

}

#3


4  

I believe for @Service you have to add qualifier name like below :

我相信@Service必须添加以下限定名:

@Service("employeeService") should solve your issue

@Service(“employeeService”)应该解决您的问题。

or after @Service you should add @Qualifier annontion like below :

或者在@Service之后添加@Qualifier annontion如下:

@Service
@Qualifier("employeeService")

#4


0  

If you only have one bean of type EmployeeService, and the interface EmployeeService does not have other implementations, you can simply put "@Service" before the EmployeeServiceImpl and "@Autowire" before the setter method. Otherwise, you should name the special bean like @Service("myspecial") and put "@autowire @Qualifier("myspecial") before the setter method.

如果您只有一种类型的EmployeeService,而接口EmployeeService没有其他实现,您可以在EmployeeServiceImpl和“@Autowire”之前将“@Service”放在setter方法之前。否则,您应该在setter方法之前命名特殊bean,比如@Service(“myspecial”),并将“@autowire @Qualifier(“myspecial”)命名为“myspecial”。

#5


0  

In your controller class, just add @ComponentScan("package") annotation. In my case the package name is com.shoppingcart.So i wrote the code as @ComponentScan("com.shoppingcart") and it worked for me.

在您的控制器类中,只需添加@ComponentScan(“package”)注释。在我的例子中,包名是com.shoppingcart。所以我把代码写为@ComponentScan(“com.shoppingcart”),它对我起作用了。

#6


0  

You forgot @Service annotation in your service class.

您在服务类中忘记了@Service注释。

#7


0  

@Service: It tells that particular class is a Service to the client. Service class contains mainly business Logic. If you have more Service classes in a package than provide @Qualifier otherwise it should not require @Qualifier.

@Service:它告诉特定的类是对客户端的服务。服务类主要包含业务逻辑。如果一个包中有更多的服务类,而不是提供@Qualifier,那么它就不需要@Qualifier。

Case 1:

案例1:

@Service("employeeService")
public class EmployeeServiceImpl implements EmployeeService{
}

Case2:

例2:

@Service
public class EmployeeServiceImpl implements EmployeeService{
}

both cases are working...

这两种情况下工作……

#8


0  

Just add below annotation with qualifier name of service in service Implementation class:

只需要在服务实现类中添加带有限定符名称的注释:

@Service("employeeService")
@Transactional
public class EmployeeServiceImpl implements EmployeeService{
}

#9


-1  

Missing the 'implements' keyword in the impl classes might also be the issue

在impl类中丢失“实现”关键字也可能是问题所在。

#1


4  

You don't have to necessarily provide name and Qualifier. If you set a name, that's the name with which the bean is registered in the context. If you don't provide a name for your service it will be registered as uncapitalized non-qualified class name based on BeanNameGenerator. So in your case the Implementation will be registered as employeeServiceImpl. So if you try to autowire with that name, it should resolve directly.

您不必提供名称和限定符。如果您设置了一个名称,那就是在上下文中注册bean的名称。如果您没有为您的服务提供一个名称,那么它将被注册为基于BeanNameGenerator的未注册的非限定类名。因此,在您的情况下,实现将注册为employeeServiceImpl。因此,如果您尝试使用该名称自动连接,它应该直接解析。

private EmployeeService employeeServiceImpl;

@RequestMapping("/employee")
public String employee() {
    this.employeeService.fetchAll();
    return "employee";
}

@Autowired(required = true)
public void setEmployeeService(EmployeeService employeeServiceImpl) {
    this.employeeServiceImpl = employeeServiceImpl;
}

@Qualifier is used in case if there are more than one bean exists of same type and you want to autowire different implementation beans for various purposes.

如果有多个bean存在相同的类型,并且您想为不同的目的自动连接不同的实现bean,则使用@Qualifier。

#2


5  

Guys I found the issue

伙计们,我发现了这个问题。

I just tried by adding the qualifier name in employee service finally it solved my issue.

我只是在员工服务中添加了qualifier的名字,最终解决了我的问题。

@Service("employeeService")

public class EmployeeServiceImpl implements EmployeeService{

}

#3


4  

I believe for @Service you have to add qualifier name like below :

我相信@Service必须添加以下限定名:

@Service("employeeService") should solve your issue

@Service(“employeeService”)应该解决您的问题。

or after @Service you should add @Qualifier annontion like below :

或者在@Service之后添加@Qualifier annontion如下:

@Service
@Qualifier("employeeService")

#4


0  

If you only have one bean of type EmployeeService, and the interface EmployeeService does not have other implementations, you can simply put "@Service" before the EmployeeServiceImpl and "@Autowire" before the setter method. Otherwise, you should name the special bean like @Service("myspecial") and put "@autowire @Qualifier("myspecial") before the setter method.

如果您只有一种类型的EmployeeService,而接口EmployeeService没有其他实现,您可以在EmployeeServiceImpl和“@Autowire”之前将“@Service”放在setter方法之前。否则,您应该在setter方法之前命名特殊bean,比如@Service(“myspecial”),并将“@autowire @Qualifier(“myspecial”)命名为“myspecial”。

#5


0  

In your controller class, just add @ComponentScan("package") annotation. In my case the package name is com.shoppingcart.So i wrote the code as @ComponentScan("com.shoppingcart") and it worked for me.

在您的控制器类中,只需添加@ComponentScan(“package”)注释。在我的例子中,包名是com.shoppingcart。所以我把代码写为@ComponentScan(“com.shoppingcart”),它对我起作用了。

#6


0  

You forgot @Service annotation in your service class.

您在服务类中忘记了@Service注释。

#7


0  

@Service: It tells that particular class is a Service to the client. Service class contains mainly business Logic. If you have more Service classes in a package than provide @Qualifier otherwise it should not require @Qualifier.

@Service:它告诉特定的类是对客户端的服务。服务类主要包含业务逻辑。如果一个包中有更多的服务类,而不是提供@Qualifier,那么它就不需要@Qualifier。

Case 1:

案例1:

@Service("employeeService")
public class EmployeeServiceImpl implements EmployeeService{
}

Case2:

例2:

@Service
public class EmployeeServiceImpl implements EmployeeService{
}

both cases are working...

这两种情况下工作……

#8


0  

Just add below annotation with qualifier name of service in service Implementation class:

只需要在服务实现类中添加带有限定符名称的注释:

@Service("employeeService")
@Transactional
public class EmployeeServiceImpl implements EmployeeService{
}

#9


-1  

Missing the 'implements' keyword in the impl classes might also be the issue

在impl类中丢失“实现”关键字也可能是问题所在。