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类中丢失“实现”关键字也可能是问题所在。