Java 在 Spring 中需要多个相同类型的 bean

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18711924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 10:23:26  来源:igfitidea点击:

Required Multiple beans of same type in Spring

javaxmlspringspring-mvcxsd

提问by dharam

A request before you mark it as duplicate. I have gone through the forum and couldn't find the solution for the problem anywhere.

将其标记为重复之前的请求。我已经浏览了论坛,但在任何地方都找不到问题的解决方案。

I am writing a code using Spring 3.2 and everything is purely annotation based. The code receives XML files which are derived form different XSD files.

我正在使用 Spring 3.2 编写代码,所有内容都完全基于注释。该代码接收从不同 XSD 文件派生的 XML 文件。

So we can say, there are five different XSD ( A1, A2, A3, A4, A5) and my code receives XML of any type, and I have the logic to identify the type of the XML upon arrival.

所以我们可以说,有五种不同的 XSD(A1、A2、A3、A4、A5),我的代码接收任何类型的 XML,我有逻辑在到达时识别 XML 的类型。

Now, I am trying to un-marshal these using Spring OXM. But because there are multiple XSDs involved, we cannot actually using one Un-marshaller. So we need around five of them.

现在,我正在尝试使用 Spring OXM 对这些进行解组。但是因为涉及多个 XSD,我们实际上不能使用一个 Un-marshaller。所以我们需要大约五个。

In the Configurationclass, I added five beans like below:

Configuration课堂上,我添加了五个豆子,如下所示:

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

Now I have five different classes C1, C2, C3, C4 and C5 and I am trying to inject one unmarshaller bean into one class. That means A1Unmarshalleris autowired to C1and so on.

现在我有五个不同的类 C1、C2、C3、C4 和 C5,我试图将一个解组器 bean 注入一个类。这意味着A1Unmarshaller自动装配到C1等等。

When the Spring context is built, it throws an error saying it expected one bean of type Jaxb2Marshallerand got five.

当构建 Spring 上下文时,它抛出一个错误,说它期望一个类型的 beanJaxb2Marshaller并得到五个。

NoteIt worked fine when done using XML configuration, so I am not sure if I am missing something. Please help.

注意使用 XML 配置完成后效果很好,所以我不确定我是否遗漏了什么。请帮忙。

EDITThe code for one of the classes C1 is below:

编辑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;
}

}

}

采纳答案by Bruce Lowe

You should qualify your autowired variable to say which one should be injected

你应该限定你的自动装配变量来说明应该注入哪个

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

The default autowiring is by type, not by name, so when there is more than one bean of the same type, you have to use the @Qualifier annotation.

默认的自动装配是按类型,而不是按名称,所以当有多个相同类型的 bean 时,你必须使用 @Qualifier 注释。

回答by M. Deinum

The Jaxb2Marshalleris perfectly capable to work with multiple different contexts/xsd. Simply specify multiple context paths by using the setContextPathsmethods.

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

That way you only need a single marshaller/unmarshaller.

这样你只需要一个编组器/解组器。

Links

链接

  1. Jaxb2Marshaller javadoc
  2. setContextPaths javadoc
  1. Jaxb2Marshaller javadoc
  2. setContextPaths javadoc

回答by Amanuel Nega

Injection using @Resourceannotation is what you're looking for. You can use

使用@Resource注解的注入正是您要找的。您可以使用

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

But that is not the only way.

但这不是唯一的方法。

@Resource("A1Unmrshaller")

Does the job too. I suggest you use the later one! See why

也做这份工作。我建议你使用后一种!看看为什么