現在、コントローラーとサービスレイヤー間のAutowire設定で問題に直面しています。
間違いを追跡することはできません。
簡易ログ情報
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: {}
以下では、コントローラーとサービス層のコード、およびdispatcher-servlet.xmlも提供しています。
コントローラー
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;
}
}
サービスインターフェイス
package com.ott.service;
import com.ott.hibernate.Employee;
import Java.util.List;
/**
*
* @author SPAR
*/
public interface EmployeeService {
List<Employee> fetchAll();
}
サービスインターフェイス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
<?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>
必ずしも名前と修飾子を提供する必要はありません。名前を設定する場合、それはBeanがコンテキストに登録される名前です。サービスの名前を指定しない場合、BeanNameGenerator
に基づいて大文字で修飾されていない非修飾クラス名として登録されます。したがって、あなたの場合、実装はemployeeServiceImpl
として登録されます。その名前で自動配線しようとすると、直接解決されるはずです。
private EmployeeService employeeServiceImpl;
@RequestMapping("/employee")
public String employee() {
employeeServiceImpl.fetchAll();
return "employee";
}
@Autowired(required = true)
public void setEmployeeService(EmployeeService employeeServiceImpl) {
this.employeeServiceImpl = employeeServiceImpl;
}
@Qualifier
は、同じタイプのBeanが複数存在し、さまざまな目的で異なる実装Beanを自動配線する場合に使用されます。
私は問題を見つけました
従業員サービスに修飾子名を追加してみたところ、ようやく問題が解決しました。
@Service("employeeService")
public class EmployeeServiceImpl implements EmployeeService{
}
_@Service
_の場合、以下のような修飾子名を追加する必要があると考えています。
@Service("employeeService")
は問題を解決するはずです
または_@Service
_の後に、以下のように_@Qualifier
_ annontionを追加する必要があります。
_@Service
@Qualifier("employeeService")
_
@Service:特定のクラスがクライアントへのサービスであることを示します。サービスクラスには、主にビジネスロジックが含まれます。パッケージに@Qualifierを提供するよりも多くのServiceクラスがある場合は、@ Qualifierを必要としません。
事例1:
@Service("employeeService")
public class EmployeeServiceImpl implements EmployeeService{
}
ケース2:
@Service
public class EmployeeServiceImpl implements EmployeeService{
}
両方のケースが機能しています...
タイプがEmployeeServiceのBeanが1つだけで、インターフェースEmployeeServiceに他の実装がない場合、単にEmployeeServiceImplの前に「@Service」を、setterメソッドの前に「@Autowire」を置くことができます。それ以外の場合は、@ Service( "myspecial")などの特別なBeanに名前を付け、setterメソッドの前に "@autowire @Qualifier(" myspecial ")を配置する必要があります。
サービスクラスで@Serviceアノテーションを忘れました。
サービス実装クラスにサービスの修飾子名を含む以下の注釈を追加するだけです:
@Service("employeeService")
@Transactional
public class EmployeeServiceImpl implements EmployeeService{
}
コントローラークラスで、@ ComponentScan( "package")アノテーションを追加するだけです。私の場合、パッケージ名はcom.shoppingcartです。そのため、コードを@ComponentScan( "com.shoppingcart")として記述しました。