繁体   English   中英

春季启动。 Bean取决于服务

[英]Spring Boot. A Bean Depends on a Service

下面有一个customUserDetailsService属性和一个tokenAuthenticationService属性。 我需要将customUserDetailsService传递给tokenAuthenticationService但是tokenAuthenticationService@Bean文件,而customUserDetailsService@Service ,这意味着首先使用UserDetailsService参数将tokenAuthenticationService调用为UserDetailsService参数的null 我需要延迟将tokenAuthenticationService作为Bean初始化或将tokenAuthenticationService转换为服务,以及一些如何将这些参数作为构造函数传递。 我该怎么做呢?

  package app.config;

    import app.repo.User.CustomUserDetailsService;
    import app.security.*;
    import app.security.filters.StatelessAuthenticationFilter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.DependsOn;
    import org.springframework.core.annotation.Order;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

    import javax.sql.DataSource;

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(securedEnabled = true)
    @Order(2)
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

        private static PasswordEncoder encoder;

        @Autowired
        private TokenAuthenticationService tokenAuthenticationService;

        @Autowired
        private UserDetailsService customUserDetailsService;

        @Autowired
        private RESTAuthenticationEntryPoint authenticationEntryPoint;
        @Autowired
        private RESTAuthenticationFailureHandler authenticationFailureHandler;
        @Autowired
        private RESTAuthenticationSuccessHandler authenticationSuccessHandler;

        public WebSecurityConfig() {
            super(true);
        }

        @Autowired
        public void configureAuth(AuthenticationManagerBuilder auth,DataSource dataSource) throws Exception {
            auth.jdbcAuthentication().dataSource(dataSource);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().antMatchers("/**").authenticated();
            http.csrf().disable();
            http.httpBasic();
            http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
            http.formLogin().defaultSuccessUrl("/").successHandler(authenticationSuccessHandler);
            http.formLogin().failureHandler(authenticationFailureHandler);
            http.addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService),
                    UsernamePasswordAuthenticationFilter.class);

        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(customUserDetailsService);
        }

        @Bean
        public TokenAuthenticationService tokenAuthenticationService() {
            tokenAuthenticationService = new TokenAuthenticationService("tooManySecrets", customUserDetailsService);
            return tokenAuthenticationService;
        }
    }

您可以将userDetailsS​​ervice定义为TokenAuthenticationService的直接依赖项,如下所示:

@Bean
public TokenAuthenticationService tokenAuthenticationService(UserDetailsService userDetailsService) {
    tokenAuthenticationService = new TokenAuthenticationService("tooManySecrets", userDetailsService);
    return tokenAuthenticationService;
}

这样,Spring将确保在创建TokenAuthenticationService时实例化并注入UserDetailsS​​ervice。

您可以尝试使用@Lazy注释tokenAuthenticationService()。 尽管即使这样做有点不可预测,但是将来对此或相关bean的修改可能会让您想知道为什么它停止工作。

最好将TokenAuthenticationService声明为@Service并在其中注入UserDetailsService

附带说明一下,最好不要将@Configuration与应用程序代码混合使用,以避免出现此类问题。

更新 -我认为@Lazy不会在这里工作。 由于您依赖于@Bean在正在处理的@Autowired bean中间被调用。

为了使您的代码正常工作,应首先设置@Autowired customUserDetailsS​​ervice,然后设置@Bean方法,然后设置@Autowired tokenAuthenticationService。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM