【问题标题】:How to Autowire a Service in a regular java bean如何在常规 java bean 中自动装配服务
【发布时间】:2016-01-04 14:36:33
【问题描述】:

我有一个 Spring 项目,我在登录成功时实现了一个审计功能。该功能有效,但我需要在登录成功时写入数据库。我的豆子是:

CustomLoginSucessHandler.java

 public class CustomLoginSucessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    final static Logger log = LoggerFactory.getLogger(CustomLoginSucessHandler.class);

    @Autowired
    private UserService userService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws ServletException, IOException {       
            final String userName = authentication.getName();
            log.debug("User name is: " + userName);
            final User user = userService.getUser(userName);

            final Date date = new Date();
            final Timestamp timeStamp = new Timestamp(date.getTime());

            user.setLastLogin(timeStamp);

            userService.saveUser(user);
            log.debug("User Last Login update to " + timeStamp);

        super.onAuthenticationSuccess(request, response, authentication);

    }

}

请注意,我有 @Autowired 注释,但它始终返回为 null

我已经尝试用@Service@Configurable注释,目前没有成功。

堆栈跟踪

java.lang.NullPointerException
    com.opessoftware.fatca.web.util.CustomLoginSucessHandler.onAuthenticationSuccess(CustomLoginSucessHandler.java:33)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:331)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:245)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:96)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)

编辑:

我如何使用我的CustomLoginSucessHandler

@Configuration
@EnableWebSecurity
@Import({ DatabaseConfiguration.class })
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/login.html")
                    .loginProcessingUrl("/login").permitAll().and().logout().logoutSuccessUrl("/")
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll().and().exceptionHandling()
                    .accessDeniedPage("/403.html");

            http.csrf().requireCsrfProtectionMatcher(new CsrfRequestMatcher());     
            http.formLogin().successHandler(new CustomLoginSucessHandler());

        }

....

【问题讨论】:

  • CustomLoginSucessHandler 不受 Spring 管理,因此 @Autowired 将不起作用。展示您如何创建和使用 CustomLoginSucessHandler 的实例
  • 你的 spring 配置文件中是否正确定义了 UserService bean?
  • @LuiggiMendoza 我编辑了问题
  • @mixmastered 是的,我可以在其他 bean 中使用 UserService。
  • 你需要有context.xml,这里需要添加<context:annotation-config />然后@Autowired@PostConstruct会被搜索到

标签: java spring spring-mvc nullpointerexception autowired


【解决方案1】:

要在控制器之外的其他上下文中获取 bean,您应该使用下一个注释:

<!--AUTOWIRED // THIS MAYBE YOU ALREADY HAVE-->
<context:component-scan base-package="com.system.rest.natura.controller" />
<!--ADD THIS ONE-->
    <context:annotation-config/>

如果你有一个或多个 spring.xml 配置存档导入它们。

<import resource="/spring-config.xml" />

你的 CustomLoginSucessHandler 也应该有注释:

@Component

【讨论】:

    【解决方案2】:

    好的,我找到了解决方案。

    首先我需要创建一个名为AuditingConfiguration.java的类

    然后这样做:

    @Configuration
    public class AuditingConfiguration {
    
        @Bean   
        public CustomLoginSucessHandler customLoginSucessHandler(){
            return new CustomLoginSucessHandler();
        }
    
    }
    

    在它之后,在我的SecurityConfiguration 里面我做了这个:

    @Configuration
    @EnableWebSecurity
    @Import({ DatabaseConfiguration.class, AuditingConfiguration.class })
    
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
        @Autowired
        private CustomLoginSucessHandler customLoginSucessHandler;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/login.html")
                    .loginProcessingUrl("/login").permitAll().and().logout().logoutSuccessUrl("/")
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll().and().exceptionHandling()
                    .accessDeniedPage("/403.html");
    
            http.csrf().requireCsrfProtectionMatcher(new CsrfRequestMatcher());     
            http.formLogin().successHandler(customLoginSucessHandler);
    
        }
    

    现在它可以工作了。

    【讨论】:

      猜你喜欢
      • 2022-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-20
      相关资源
      最近更新 更多