Требуется несколько beans одного типа в Spring

Запрос перед тем, как пометить его как дубликат. Я прошел через форум и не смог найти решение проблемы в любом месте.

Я пишу код, используя Spring 3.2, и все чисто основано на аннотациях. Код получает XML файлы, которые получены из разных XSD файлов.

Итак, мы можем сказать, что существует пять разных XSD (A1, A2, A3, A4, A5), и мой код получает XML любого типа, и у меня есть логика для идентификации типа XML по прибытии.

Теперь я пытаюсь отключить их с помощью Spring OXM. Но поскольку задействовано несколько XSD, мы не можем использовать один Un-marshaller. Поэтому нам нужно около пяти из них.

В классе Configuration я добавил пять beans, как показано ниже:

@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");
}

Теперь у меня есть пять разных классов C1, C2, C3, C4 и C5, и я пытаюсь вставить один unmarshaller bean в один класс. Это означает, что A1Unmarshaller автоматически добавляется к C1 и т.д.

Когда создается контекст Spring, он выдает ошибку, говоря, что он ожидал один bean типа Jaxb2Marshaller и получил пять.

Примечание. Он отлично работал, когда был выполнен с использованием конфигурации XML, поэтому я не уверен, что что-то не хватает. Пожалуйста, помогите.

EDIT Код для одного из классов C1 ниже:

@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;
}

}

Ответ 1

Вы должны квалифицировать свою переменную с автоподстановкой, чтобы сказать, какой из них следует ввести

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

Автоустановка по умолчанию - по типу, а не по имени, поэтому, когда существует более одного bean того же типа, вы должны использовать аннотацию @Qualifier.

Ответ 2

Инъекция с использованием аннотации @Resource - это то, что вы ищете. Вы можете использовать

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

Но это не единственный способ.

@Resource("A1Unmrshaller")

Работает тоже. Я предлагаю вам использовать более поздний! Посмотрите, почему

Ответ 3

Jaxb2Marshaller отлично работает с несколькими различными контекстами /xsd. Просто укажите несколько путей контекста, используя методы 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;
}

Таким образом вам нужен только один маршаллер /unmarshaller.

Ссылки