1

My interface:

public interface SomeInterface {}

is implemented by a request-scoped bean:

@Component
@Qualifier("q")
@Scope(value = WebApplicationContext.SCOPE_REQUEST,
       proxyMode = ScopedProxyMode.INTERFACES)
public class Implementation implements SomeInterface { }

Considering advice like INTERFACES or TARGET_CLASS: Which proxyMode should I choose? suggests the proxy mode INTERFACES should fit this pretty clean setup.

As I want to end up with several alternative implementations of SomeInterface, I throw in an additional @Qualifier("q").

However, Spring rejects the qualifier completely, behaving as if there was no suitable @Component around.

For example, the following test fails with the typical UnsatisfiedDependencyException saying Spring "expected at least 1 bean which qualifies as autowire candidate", but found none for @org.springframework.beans.factory.annotation.Qualifier(value=q).

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SomeInterface.class, Implementation.class})
public class AutowiringTest {

    @Autowired
    @Qualifier("q")
    private SomeInterface cut;

    @Test
    public void autowires() {
        assertThat(cut).isInstanceOf(SomeInterface.class);
    }

}

In contrast, choosing the standard bean name makes the thing work:

@Autowired
@Qualifier("implementation")
private SomeInterface cut; // <-- works

Also, varying the standard bean name instead of adding a @Qualifier makes the thing work:

@Component("q")
@Scope(value = WebApplicationContext.SCOPE_REQUEST, 
       proxyMode = ScopedProxyMode.INTERFACES)
public class Implementation implements SomeInterface { }

Also, changing the proxy mode to TARGET_CLASS makes the thing work:

@Component("q")
@Scope(value = WebApplicationContext.SCOPE_REQUEST, 
       proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Implementation implements SomeInterface { }

What is so special about the proxy mode INTERFACES that it won't work in combination with @Qualifier?

Florian
  • 4,821
  • 2
  • 19
  • 44
  • Your test passes if you remove the Qualifier annotation on the Implementation class and use `@Component("q")`to set the component name. But I have no idea why it doesn't work with the qualifier, and why it does if you remove the Scope annotation. – JB Nizet Oct 12 '19 at 17:12

0 Answers0