2016-01-12 1 views
0

Quelle est la manière correcte de câbler des composants dans Spring? Actuellement, j'ai deux classes qui implémentent une interface, et si @Autowire l'interface dans deux classes d'implémentation, Spring est confus quant à la classe d'implémentation qu'il devrait utiliser. Donc d'abord j'ai essayé d'utiliser une annotation @Component ("name") dans les deux différentes implémentations pour leur donner des noms différents (si je comprends bien), mais ça a quand même échoué. Finalement, j'ai fini par déclarer les implémentations Dao spécifiques (j'ai plusieurs implémentations Dao) dans les classes Service, car j'ai eu une erreur en disant que j'avais deux implémentations, et je n'en attendais qu'une seule. (NoUniqueBeanDefinitionException: Aucun grain de qualification de type est défini: haricot simple correspondant attendu, mais 2)Implémentations de câblage dans Spring MVC utilisant l'annotation @Autowired

code impliqué dans la question (s'il vous plaît demander plus si elle aide)

printemps-servlet.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:p="http://www.springframework.org/schema/p" 
     xmlns:mvc="http://www.springframework.org/schema/mvc" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> 

    <context:annotation-config /> 

    <context:component-scan base-package="studyeasy"/> 

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

    <!-- datasource bean --> 
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
     <property name="url" value="***" /> 
     <property name="username" value="***" /> 
     <property name="password" value="***" /> 
    </bean> 

    <mvc:resources mapping="/resources/**" location="/resources/" /> 
    <mvc:annotation-driven/> 

</beans> 

DatabaseDao.java:

package studyeasy.dao; 

import ...; 

public interface DatabaseDao { 
    public void insertObject(Object obj); 
    public List<Object> getObjectList(); 
    public void updateObject(Object obj); 
    public void deleteObject(String id); 
    public Object getObject(String id); 
} 

PersonDaoImpl.java:

package studyeasy.dao; 

import javax.sql.DataSource; 
import ...; 

@Repository 
public class PersonDaoImpl implements DatabaseDao { 

    @Autowired 
    DataSource dataSource; 

    @Override 
    public void insertObject(Object obj) { 
     ... 
    } 

    ... 

} 

UtilityDaoImpl.java:

package studyeasy.dao; 

import javax.sql.DataSource; 
import ...; 

@Repository 
public class UtilityDaoImpl implements DatabaseDao { 
    @Autowired 
    DataSource dataSource; 

    @Override 
    public void insertObject(Object obj) { 
     ... 
    } 

    ... 
} 

DatabaseService.java:

package studyeasy.services; 

import ...; 

public interface DatabaseService { 
    public void insertObject(Object object); 
    public List<Object> getObjectList(); 
    public void deleteObject(String id); 
    public Object getObject(String id); 
    public void updateObject(Object object); 
} 

PersonServiceImpl.java:

package studyeasy.services; 

import studyeasy.dao.PersonDaoImpl; 
import ...; 

@Service 
public class PersonServiceImpl implements DatabaseService { 

    @Autowired 
    PersonDaoImpl personDao; 

    @Override 
    public void insertObject(Object object) { 
     ... 
    } 

    ... 
} 

UtilityServiceImpl.java:

package studyeasy.services; 

import studyeasy.dao.UtilityDaoImpl; 
import ...; 

@Service 
public class UtilityServiceImpl implements DatabaseService { 

    @Autowired 
    UtilityDaoImpl utilityDao; 

    @Override 
    public void insertObject(Object obj) { 
     ... 
    } 

    ... 
} 

Toutes les suggestions?

EDIT:

Après avoir ajouté @ aux deux ServiceImpl classes de Qualifier, je reçois cette erreur:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [studyeasy.dao.DatabaseDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=personDao)} 

Toutes les idées pourquoi?

Répondre

0

Nom vos haricots et utiliser le org.springframework.beans.factory.annotation.annotation Qualifier pour définir le bean au fil par son nom

exemple:

@Autowired 
@Qualifier("someDataSource") 
DataSource dataSource; 
+0

Après avoir ajouté Qualifier à toutes mes classes (dois-je ajouter un Qualificateur à chaque classe?), Je peux déclarer l'interface des classes d'implémentation DAO dans les classes de service? Comme '@Autowired @Qualifier ("utilityDao") DatabaseDao databaseDao,' – LifeOfAStudent

+0

Dans l'annotation @Qualifier vous définissez le nom du grain que vous voulez fil. Le nom du bean est spécifié dans la définition du bean. ex: @component ("mybeanName") MyBeanImpl public class implémente MyBean { (...) –

0

Vous devez utiliser @Qualifier pour distinguer les haricots à utiliser candidat:

@Autowired @Qualifier("fooBean") MyBean bean; 

Notez que l'injection de constructeur est loin préférable à l'injection sur le terrain, et si vous utilisez la configuration Java, vous pouvez simplement appeler votre constructeur avec l'implémentation appropriée.

(Comme une note finale. Si vous utilisez printemps de données, vous pouvez probablement vous mettre en œuvre OTI entièrement et les ont générées automatiquement pour vous)

+0

Après avoir ajouté Qualifier à toutes mes classes (dois-je ajouter un Qualifier à chaque classe?), Je peux déclarer l'interface des classes d'implémentation DAO dans les classes de service? Comme '@Autowired @Qualifier (" utilityDao ") DatabaseDao databaseDao;' – LifeOfAStudent

+0

@LifeOfAStudent Vous avez seulement besoin d'ajouter le qualificatif à l'élément que vous essayez de câbler. Cela dit, cependant, votre cas d'utilisation semble être que vous essayez vraiment d'éviter un bon design d'API (celui qui est * au moins * générique dans ce cas). – chrylis

+0

Pourriez-vous regarder mon édition dans OP? – LifeOfAStudent