1

I've specified Qualifier on both autowired et bean method.

So What am i missing ?

@Configuration
@EnableWebSecurity
public class CustomSecurityCOnfig  {

    @Bean
    @Qualifier("entryPoint")
    AuthenticationEntryPoint loginUrlAuthenticationEntryPoint() {
        return new LoginUrlAuthenticationEntryPoint("/login");
    }

}

I autowire the field this way

@Autowired
    @Qualifier("entryPoint")
    private AuthenticationEntryPoint loginUrlAuthenticationEntryPoint;

Stacktrace of the error :

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.core.env.Environment' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1716) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1272) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]

EDIT I Have another implementation of AuthenticationEntryPoint interface :

@Component
public class CustomAuthenticationEntryPoint extends BasicAuthenticationEntryPoint

But in my opinion it doesn't explain the error (as long as i specify the qualifiers)

soung
  • 1,411
  • 16
  • 33

1 Answers1

1

You're mixing bean name and Qualifier

@Bean(name="someFancyBean")
public ClassXyx fooBar(){
    return new ClassXyz()
}

In this example, method fooBar creates a bean of type ClassXyx and it's named someFancyBean. If you want to auto-wire this bean then you have to use

@Service
class SomeFancyService{
  @Autowired @Qualifier("someFancyBean") ClassXyx xyz;
}

A configuration class can create multiple beans of the same type but their names are derived from function name. There's no point in using Bean annotation with name="XYZ" unless you want to rename that bean.

The Qualifier annotation is used for referring one of the beans of the same type.

Now coming back to your code

@Configuration
@EnableWebSecurity
public class CustomSecurityCOnfig  {

    @Bean
    public AuthenticationEntryPoint entryPoint() {
        return new LoginUrlAuthenticationEntryPoint("/login");
    }

}

In your service you have to Autowired as.

@Autowired
@Qualifier("entryPoint")
private AuthenticationEntryPoint loginUrlAuthenticationEntryPoint;

Also, I would like to point one more thing bean accessibility across package/class.

Generally, all beans created by Spring IOC are public, but it has the same access modifier like Java classes. If you're creating a bean with package scope then you can't auto-wire in another package. Similarly, if a bean is created using private then that bean can be only auto-wired in that class.

sonus21
  • 5,178
  • 2
  • 23
  • 48