We have struts 1.x used with Spring 3.x in our project. In the process of upgrading from spring 3->4, our qualifier annotation in the struts action does not work any more. After digging in and compare the Spring 3 and 4, finally found the reason.
1.QualifierAnnotationAutowireCandidateResolver is not the default resolver in spring 4
In Spring 3, after we create our beanfacotry in the application context, Spring will explicitly call :
In spring 4, it is not called any more in the AbstractRefreshableApplicationContext’s protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory).
So for the parent(root) context, it should still work as is if you have the <context:annotation-config/> in the config xml. However for the child context the default resolver will become ‘SimpleAutowireCandidateResolver’
2.The child resolver is passed to parent when trying to determine ‘isAutowireCandidate()’ in Spring 4’s DefaultListableBeanFactory
The isAutowireCandidate() will delegate the responsibility to parent beanFactory if it cannot make decision.
In Spring 3, the delegation does not pass the resolver to the parent so that parent context uses its own resolver to call the isAutowireCandidate(). However in Spring 4, it changes. The resolver is passed as a parameter to the parent who uses it to call the isAutowireCandidate(). So even the parent has a ContextAnnotationAutowireCandidateResolver which extends QualifierAnnotationAutowireCandidateResolver as its resolver, it still does not help.
The simple solution to me is to set the resolver to QualifierAnnotationAutowireCandidateResolver using a BeanFactoryPostProcessor. The good thing is Spring already provided one for us.
So the config should be added to the CHILD context config xml
<bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"> <property name="customQualifierTypes"> <set> <value>org.springframework.beans.factory.annotation.Qualifier</value> </set> </property> </bean>