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 to C1
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; }
}
It's not possible. You get a duplicate exception. It's also far from optimal with configuration data like this in your implementation classes. But you're using a separate factory for each different Spring bean you create.
The limitation of this approach is that we need to manually instantiate beans using the new keyword in a typical Java-based configuration style. Therefore, if the number of beans of the same class increases, we need to register them first and create beans in the configuration class.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With