web-dev-qa-db-fra.com

Plusieurs beans de même type requis au printemps

Une demande avant de le marquer comme doublon. J'ai parcouru le forum et je n'ai trouvé la solution au problème nulle part.

J'écris un code en utilisant Spring 3.2 et tout est purement basé sur des annotations. Le code reçoit des fichiers XML dérivés de différents fichiers XSD.

Nous pouvons donc dire qu'il existe cinq XSD différents (A1, A2, A3, A4, A5) et mon code reçoit du XML de tout type, et j'ai la logique d'identifier le type du XML à l'arrivée.

Maintenant, j'essaye de les dissocier en utilisant Spring OXM. Mais parce qu'il y a plusieurs XSD impliqués, nous ne pouvons pas réellement utiliser un Un-marshaller. Nous avons donc besoin d'environ cinq d'entre eux.

Dans la classe Configuration, j'ai ajouté cinq beans comme ci-dessous:

@Bean(name="A1Unmarshaller")
public Jaxb2Marshaller A1Unmarshaller(){
    Jaxb2Marshaller unMarshaller = new Jaxb2Marshaller();
    unMarshaller.setContextPath("package name for the classes generate by XSD A1");
}

@Bean(name="A2Unmarshaller")
public Jaxb2Marshaller A1Unmarshaller(){
    Jaxb2Marshaller unMarshaller = new Jaxb2Marshaller();
    unMarshaller.setContextPath("package name for the classes generate by XSD A2");
}

@Bean(name="A3Unmarshaller")
public Jaxb2Marshaller A3Unmarshaller(){
    Jaxb2Marshaller unMarshaller = new Jaxb2Marshaller();
    unMarshaller.setContextPath("package name for the classes generate by XSD A3");
}

@Bean(name="A4Unmarshaller")
public Jaxb2Marshaller A4Unmarshaller(){
    Jaxb2Marshaller unMarshaller = new Jaxb2Marshaller();
    unMarshaller.setContextPath("package name for the classes generate by XSD A4");
}

@Bean(name="A5Unmarshaller")
public Jaxb2Marshaller A5Unmarshaller(){
    Jaxb2Marshaller unMarshaller = new Jaxb2Marshaller();
    unMarshaller.setContextPath("package name for the classes generate by XSD A5");
}

Maintenant, j'ai cinq classes différentes C1, C2, C3, C4 et C5 et j'essaie d'injecter un bean unmarshaller dans une classe. Cela signifie A1Unmarshaller est câblé automatiquement à C1 etc.

Lorsque le contexte Spring est créé, il génère une erreur indiquant qu'il attendait un bean de type Jaxb2Marshaller et j'en ai eu cinq.

Remarque Cela a bien fonctionné lorsque vous avez terminé d'utiliser la configuration XML, donc je ne suis pas sûr de manquer quelque chose. Veuillez aider.

EDIT Le code de l'une des classes C1 est ci-dessous:

@Component
public class C1{

@Autowired
private Jaxb2Marshaller A1Unmarshaller;
    A1 o = null

public boolean handles(String event, int eventId) {
    if (null != event&& eventId == 5) {
                A1 =  A1Unmarshaller.unMarshal(event);
        return true;
    }
    return false;
}

}

23
dharam

Vous devez qualifier votre variable auto-câblée pour dire laquelle doit être injectée

@Autowired
@Qualifier("A1Unmarshaller")
private Jaxb2Marshaller A1Unmarshaller;

Le câblage automatique par défaut est par type, pas par nom, donc quand il y a plus d'un bean du même type, vous devez utiliser l'annotation @Qualifier.

43
Bruce Lowe

Le Jaxb2Marshaller est parfaitement capable de fonctionner avec plusieurs contextes différents/xsd. Spécifiez simplement plusieurs chemins de contexte en utilisant les méthodes setContextPaths .

@Bean(name="A1Unmarshaller")
public Jaxb2Marshaller A1Unmarshaller(){
    Jaxb2Marshaller unMarshaller = new Jaxb2Marshaller();
    unMarshaller.setContextPaths(
        "package name for the classes generate by XSD A1",
        "package name for the classes generate by XSD A2",
        "package name for the classes generate by XSD A3",
        "package name for the classes generate by XSD A4",
        "package name for the classes generate by XSD A5" );
    return unMarshaller;
}

De cette façon, vous n'avez besoin que d'un seul marshaller/unmarshaller.

Liens

  1. Jaxb2Marshaller javadoc
  2. setContextPaths javadoc
4
M. Deinum

Injection à l'aide de @Resource l'annotation est ce que vous recherchez. Vous pouvez utiliser

@AutoWired
@Qualifier("A1Unmarshaller")
private Jaxb2Marshaller A1Unmarshaller;

Mais ce n'est pas le seul moyen.

@Resource("A1Unmrshaller")

Fait le travail aussi. Je vous suggère d'utiliser le dernier! Voir pourquoi

4
Amanuel Nega