【问题标题】:What happens when i using @Bean and @Component annotations together?当我同时使用@Bean 和@Component 注释时会发生什么?
【发布时间】:2021-11-08 01:37:26
【问题描述】:

我正在尝试配置我的 spring 安全应用程序。

我想创建自己的 UserDetailsS​​ervice。

为此我做了这样的事情:

public class ApplicationUserService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return this.someUser();
    }
}

我有两种方法可以将此 UserService 添加到 Spring Security

  1. 将其添加到配置类。像这样:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        return applicationUserService;
    }
}
  1. 或者在我的类上添加注释@Component 或@Service。 当我只选择一种方式时,一切正常,但我有一个问题:为什么当我尝试同时使用这两种变体(添加 @Service 并将 @Bean 添加到配置)时没有任何效果? 我在控制台中没有出现异常、错误或类似情况:
2021-09-11 17:26:16.755  INFO 15819 --- [           main] com.example.test.TestApplication         : Starting TestApplication using Java 16.0.2 on aleksander-MS-7A71 with PID 15819 (/home/aleksander/programming/java/4fun/test/target/classes started by aleksander in /home/aleksander/programming/java/4fun/test)
2021-09-11 17:26:16.756  INFO 15819 --- [           main] com.example.test.TestApplication         : No active profile set, falling back to default profiles: default
2021-09-11 17:26:17.402  INFO 15819 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-09-11 17:26:17.409  INFO 15819 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-09-11 17:26:17.409  INFO 15819 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.52]
2021-09-11 17:26:17.442  INFO 15819 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-09-11 17:26:17.442  INFO 15819 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 630 ms
2021-09-11 17:26:17.555  INFO 15819 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@6981f8f3, org.springframework.security.web.context.SecurityContextPersistenceFilter@38bb9d7a, org.springframework.security.web.header.HeaderWriterFilter@62db3891, org.springframework.security.web.authentication.logout.LogoutFilter@48528634, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@80bfdc6, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@78d6447a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5e65afb6, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@623dcf2a, org.springframework.security.web.session.SessionManagementFilter@2819c460, org.springframework.security.web.access.ExceptionTranslationFilter@6f49d153, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@60bbacfc]
2021-09-11 17:26:17.676  INFO 15819 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-09-11 17:26:17.682  INFO 15819 --- [           main] com.example.test.TestApplication         : Started TestApplication in 1.215 seconds (JVM running for 1.794)

【问题讨论】:

标签: spring spring-boot spring-security


【解决方案1】:

按照您描述问题的方式,除非您定义了 bean 首选项,否则应用程序肯定会抛出异常。

第一种情况: 基本上,UserDetailsService 是一个 interface,并且您通过将 bean 声明为

来提供它的实现
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        return new ApplicationUserService();
    }
}

第二种情况:您想通过使用@Service@Component 注释声明另一个bean 来检查行为,如下所示

@Service
public class ApplicationUserService implements UserDetailsService {  
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return new UserDetails();
    }
}

如果您尝试将上述情况一起使用,它将无法正常工作。案例非常简单,您向 spring 容器提供了两个 UserDetailsService 类型的 bean,因此它无法识别应该使用哪一个。

如果您想检查这两种情况的行为,您必须为 bean 设置优先级,因此在这种情况下,您可以使用 @Primary 注释标记其中一个 bean。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Primary
    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        return new ApplicationUserService();
    }
}

【讨论】:

  • 感谢您的帮助!
猜你喜欢
  • 2016-01-15
  • 1970-01-01
  • 1970-01-01
  • 2011-09-17
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多