Required Multiple beans of same type in Spring
Solution 1
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.
Solution 2
The Jaxb2Marshaller
is perfectly capable to work with multiple different contexts/xsd. Simply specify multiple context paths by using the setContextPaths methods.
@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
Solution 3
Injection using @Resource
annotation is what you're looking for. 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
dharam
Updated on December 10, 2020Comments
-
dharam over 3 years
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.
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.
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.
In the
Configuration
class, I added five beans like below:@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. That means
A1Unmarshaller
is autowired toC1
and so on.When the Spring context is built, it throws an error saying it expected one bean of type
Jaxb2Marshaller
and got five.Note It worked fine when done using XML configuration, so I am not sure if I am missing something. Please help.
EDIT The code for one of the classes C1 is below:
@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; }
}
-
UHDante over 4 yearsThis help me a lot, thx! That "s" -> setContextPath"s" save my day.