I faced a similar issue recently, and I believe the solution I come up is different from the accepted answer, which I think it worth to raise it for reference.
Let me make sure my understanding on your situation is right:
In dispatcher-context, you have:
- created the jaxb2 marshaller
- created the controllers.
- in one of the controller, you tried to inject the marshaller (through annotation)
However the injection failed. And when move the creation of JAXB2 Marshaller to the root context, it works.
If my description of your situation is right, then keep on reading:
What you have done is in fact correct: JAXB2 Marshaller and the Controller beans are created in the same context (the dispatcher-context) and Controller bean should be able to be injected with the marshaller bean.
The problem is possibly in the root context, you have created another controller bean. And it is that extra controller bean in root context cannot be injected with the marshaller (because marshaller bean exists in a child context which cannot be accessed). Therefore when you move the marshaller bean to root context, everything seems work (because both Controller in root context and dispatcher context can see the marshaller bean)
The common problem is in your root context xml, you have component-scan
declared. By default, component-scan
will include classes annotated with @Controller
during its scan. This bring another controller bean in your root context.
If it is the case, solution is straight-forward: simply exclude Controller in root context component scan (and include only Controller in dispatcher context component scan)
root context xml:
<context:component-scan base-package="com.foo">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
dispatcher context xml:
<context:component-scan base-package="com.foo" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>