简体   繁体   English

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

[英]Required Multiple beans of same type in Spring

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.我正在使用 Spring 3.2 编写代码,所有内容都完全基于注释。 The code receives XML files which are derived form different XSD files.该代码接收从不同 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.现在,我正在尝试使用 Spring OXM 对这些进行解组。 But because there are multiple XSDs involved, we cannot actually using one Un-marshaller.但是因为涉及多个 XSD,我们实际上不能使用一个 Un-marshaller。 So we need around five of them.所以我们需要大约五个。

In the Configuration class, I added five beans like below:Configuration类中,我添加了五个 bean,如下所示:

@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 A2Unmarshaller(){
    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.现在我有五个不同的类 C1、C2、C3、C4 和 C5,我试图将一个解组器 bean 注入一个类。 That means A1Unmarshaller is autowired to C1 and so on.这意味着A1Unmarshaller会自动连接到C1 ,依此类推。

When the Spring context is built, it throws an error saying it expected one bean of type Jaxb2Marshaller and got five.当构建 Spring 上下文时,它抛出一个错误,指出它期望一个类型为Jaxb2Marshaller bean 并得到五个。

Note It worked fine when done using XML configuration, so I am not sure if I am missing something.注意使用 XML 配置完成后效果很好,所以我不确定我是否遗漏了什么。 Please help.请帮忙。

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

} }

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 注释。

The Jaxb2Marshaller is perfectly capable to work with multiple different contexts/xsd. Jaxb2Marshaller完全能够处理多个不同的上下文/xsd。 Simply specify multiple context paths by using the setContextPaths methods.只需使用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 Jaxb2Marshaller javadoc
  2. setContextPaths javadoc setContextPaths javadoc

Injection using @Resource annotation is what you're looking for.使用@Resource注释的注入正是您要寻找的。 You can use您可以使用

@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看看为什么

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM