Skip to content

@Qualifier Change of Behavior 4.0 Vs 3.x with Qualified Bean in Parent Context [SPR-10966] #15594

@spring-projects-issues

Description

@spring-projects-issues

Gary Russell opened SPR-10966 and commented

I don't know if this is a bug in 4.0 or 3.x; I suspect the latter but there is probably an argument for the former...

This was discovered when moving XD to Spring 4.0.0.M3.

In 4.0, an @Qualifier in a child context is not resolved to a <qualifier/> bean in a parent context, unless the parent context has <context:annotation-config/>.

Consider the following

child-context.xml

	<context:component-scan base-package="foo" />

and

parent-context.xml

	<bean id="foo" class="foo.BrokenQualifier$BarImpl">
		<constructor-arg value="foo" />
		<qualifier value="baz" />
	</bean>

	<bean id="bar" class="foo.BrokenQualifier$BarImpl">
		<constructor-arg value="bar" />
	</bean>

and

package foo;

public class BrokenQualifier {

	public static void main(String[] args) {
		ApplicationContext parent = new ClassPathXmlApplicationContext("parent-context.xml", BrokenQualifier.class);
		ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext(parent);
		child.setConfigLocation("foo/child-context.xml");
		child.refresh();

		System.out.println(child.getBean(Baz.class).getFoo());

		child.close();
	}

	@Component
	public static class Baz {

		private final String foo;

		@Autowired
		public Baz(@Qualifier("baz") Bar aBar) {
			this.foo = aBar.getBar();
		}

		public String getFoo() {
			return foo;
		}

	}

	public interface Bar {

		public String getBar();
	}

	public static class BarImpl implements Bar {

		private final String bar;

		public BarImpl(String bar) {
			this.bar = bar;
		}

		@Override
		public String getBar() {
			return bar;
		}

	}
}

Notice that the Baz constructor has an Qualifier matching the <qualifier/> in the parent context. All works fine with 3.x; with 4.0, we get

No qualifying bean of type [foo.BrokenQualifier$Bar] is defined: expected single matching bean but found 2: foo,bar

Adding <context:annotation-config/> to the parent context makes it work (as does changing the constructor parameter name from 'aBar' to 'foo').


Affects: 4.0 M3

Referenced from: commits eb1b3c5

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: regressionA bug that is also a regression

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions