field myuserdetailsservice需要一个bean,但找到了2个

zy1mlcev  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(317)

完全错误:com.api.websecurityconfig中的字段myuserdetailsservice需要一个bean,但找到2个:
user1:在文件[/tools/tomcat/instances/webapps/api/webinf/classes/com/api/jwt/users/test1.class]中定义
user2:在文件[/tools/tomcat/instances/webapps/api/webinf/classes/com/api/jwt/users/test2.class]中定义
我有以下课程:
测试1.java

@Service
@Component("user1")
public class Test1 implements UserDetailsService {

    @Value("${test1.username}")
    private String test1Username;

    @Value("${test1.password}")
    private String test1Password;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        if (username != null && username.equals(test1Username)) {
            return new User(username, test1Password, new ArrayList<>());
        } else {
            throw new UsernameNotFoundException("Username not found: " + username);
        }
    }

}

测试2.java

@Service
@Component("user2")
public class Test2 implements UserDetailsService {

    @Value("${test2.username}")
    private String test2Username;

    @Value("${test2.password}")
    private String test2Password;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        if (username != null && username.equals(test2Username)) {
            return new User(username, test2Password, new ArrayList<>());
        } else {
            throw new UsernameNotFoundException("Username not found: " + username);
        }
    }

}

SpringMain应用程序.java

@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService myUserDetailsService;

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable()
            .authorizeRequests().antMatchers("/**/access-token").permitAll().
            anyRequest().authenticated().and().
            exceptionHandling().and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

}

jwtrequestfilter.java文件

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Autowired
    @Qualifier(value = "user1")
    private Test1 test1;

    @Autowired
    @Qualifier(value = "user2")
    private Test2 test2;

    @Override
    protected void doFilterInternal() throws ServletException, IOException {
        // SOME CODE
    }

我想通过使用 @Component 以及 @Qualifier ,我可以设置两个用户详细信息类,但事实似乎并非如此。
在这个设计中,有没有什么是我遗漏的或是不可能的?
如果我把另一个类命名为 MyUserDetailsService.java 然后在相应的端点中访问编译工作和正确的类。我只是不明白为什么 MyUserDetailsService 必须存在,我不能使用 Test1 以及 Test2 作为用户类。
编辑:
测试1.java

@Service
@Component("myUserDetailsService")
public class Test1 implements UserDetailsService {

    @Value("${test1.username}")
    private String test1Username;

    @Value("${test1.password}")
    private String test1Password;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        if (username != null && username.equals(test1Username)) {
            return new User(username, test1Password, new ArrayList<>());
        } else {
            throw new UsernameNotFoundException("Username not found: " + username);
        }
    }

}

测试2.java

@Service
@Component("myUserDetailsService")
public class Test2 implements UserDetailsService {

    @Value("${test2.username}")
    private String test2Username;

    @Value("${test2.password}")
    private String test2Password;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        if (username != null && username.equals(test2Username)) {
            return new User(username, test2Password, new ArrayList<>());
        } else {
            throw new UsernameNotFoundException("Username not found: " + username);
        }
    }

}

SpringMain应用程序.java

@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier(value = "myUserDetailsService")
    private UserDetailsService myUserDetailsService;

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable()
            .authorizeRequests().antMatchers("/**/access-token").permitAll().
            anyRequest().authenticated().and().
            exceptionHandling().and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

}

jwtrequestfilter.java文件

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Autowired
    private Test1 test1;

    @Autowired
    private Test2 test2;

    @Override
    protected void doFilterInternal() throws ServletException, IOException {
        // SOME CODE
    }

这会导致以下错误:

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.api.SpringMainApplication];

nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException:

Annotation-specified bean name 'myUserDetailsService' for bean class [com.api.jwt.users.Test2DetailsService] conflicts with existing, non-compatible bean definition of same name and class [com.api.jwt.users.Test1DetailsService]
w8f9ii69

w8f9ii691#

这些声明不需要限定符。spring可以按类型注入这些bean,因为每个类型都有一个匹配的bean(test1和test2)。

@Autowired
@Qualifier(value = "user1")
private Test1 test1;

@Autowired
@Qualifier(value = "user2")
private Test2 test2;

但是,您确实需要为这个声明提供一个限定符,因为您有两个 UserDetailsService spring不知道要注入哪一个,导致了错误。

@Autowired
private UserDetailsService myUserDetailsService;

编辑
在更新的示例中,您定义了两个具有相同bean id的bean

@Component("myUserDetailsService")
public class Test1 implements UserDetailsService {

@Component("myUserDetailsService")
public class Test2 implements UserDetailsService {

这将导致您看到的新错误(查看spring文档可能会有所帮助):
为bean类[com.api.jwt.users.test2detailsservice]指定的注解bean名称“myuserdetailsservice”与相同名称和类[com.api.jwt.users.test1detailsservice]的现有不兼容bean定义冲突
在你的例子中,有两个是没有意义的 UserDetailsService 实现。您可以通过将它们组合到一个类中来重构。

相关问题