Springboot过滤器中注入Bean

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Springboot过滤器中注入Bean

今天被人提了个问题——在过滤器(Filter)中注入Bean后拿不到对象(为null),如何避免这个坑?
废话不多说了,咱们直接看解决方案代码吧!
首先来看一下过滤器中的内容:
认证过滤器配置了,获取用户输入用户名和密码方法,认证成功方法及认证失败处理方法,以及日志入库封装代码;
当认证成功后,记录日志入库的时候,会发现此处的journalService是null,无法获取相对应的Bean对象,
java复制代码

/**
 * 认证过滤器
 */
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {
   

    private Logger logger = LoggerFactory.getLogger(TokenLoginFilter.class);
    private TokenManager tokenManager;
    private JournalService journalService;
    private RedisTemplate redisTemplate;
    // 权限管理工具,由SpringSecurity封装提供
    private AuthenticationManager authenticationManager;

    public TokenLoginFilter(AuthenticationManager authenticationManager, TokenManager tokenManager, RedisTemplate redisTemplate,JournalService journalService) {
   
        this.authenticationManager = authenticationManager;
        this.tokenManager = tokenManager;
        this.redisTemplate = redisTemplate;
        this.journalService = journalService;
        this.setPostOnly(false);
    }

    // 1 获取表单提交用户名和密码
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
   
        //获取表单提交数据
        try {
   
            User user = new ObjectMapper().readValue(request.getInputStream(), User.class);
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword(),
                    new ArrayList<>()));
        } catch (IOException e) {
   
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    // 2 认证成功调用的方法
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response, FilterChain chain, Authentication authResult)
            throws IOException, ServletException {
   

        insertJournal(user,request);

        ResponseUtil.out(response, apiResult);
    }

    // 3  认证失败调用的方法
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)
            throws IOException, ServletException {
   
        logger.info("认证登录失败,失败原因:{}",failed.getMessage());
        ApiResult apiResult = new ApiResult();
        apiResult.setResultCode(ApiResponse.FAIL.getResCode());
        apiResult.setMsg("用户名密码错误");
        ResponseUtil.out(response, apiResult);
    }

    @Async
    public void insertJournal(SecurityUser user,HttpServletRequest request) throws BaseException {
   
        Journal journal = new Journal();
        journal.setCreateTime(new Date());
        journal.setMethod("login");
        journal.setName(user.getUsername());
        journal.setIpAddress(IpUtils.getIp(request));
        journal.setRemark("登录成功");
        journalService.insertSelective(journal);
    }

}

通过上面的代码便是拦截其中注入Bean的操作,此时如果没有任何配置,则注入的Bean全部获取不到对象值,全部为null
接下来我们看解决方案:
次配置类中公共构造函数中会按照系统注入所需要的tokenManager、redisTemplate、defaultPasswordEncoder、userDetailsService、journalServiced对象。
相对应的配置设置会实现商法所说的注入动作,这样即可完成正确的Bean注入操作


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter {
   

    private TokenManager tokenManager;
    private RedisTemplate redisTemplate;
    private DefaultPasswordEncoder defaultPasswordEncoder;
    private UserDetailsService userDetailsService;
    private JournalService journalService;

    @Autowired
    public TokenWebSecurityConfig(UserDetailsService userDetailsService, DefaultPasswordEncoder defaultPasswordEncoder,
                                  TokenManager tokenManager, RedisTemplate redisTemplate,JournalService journalService) {
   
        this.userDetailsService = userDetailsService;
        this.defaultPasswordEncoder = defaultPasswordEncoder;
        this.tokenManager = tokenManager;
        this.redisTemplate = redisTemplate;
        this.journalService = journalService;
    }

    /**
     * 配置设置
     * @param http
     * @throws Exception
     */
    // 设置退出的地址和token,redis操作地址
    @Override
    protected void configure(HttpSecurity http) throws Exception {
   
        http.cors();
        http.exceptionHandling()
                .authenticationEntryPoint(new UnauthEntryPoint()) // 没有权限访问
                .and().csrf().disable()
                .authorizeRequests()
                .anyRequest().authenticated() //任何请求,登录后可以访问
                .and().logout().logoutUrl("/index/logout")//退出路径
                .addLogoutHandler(new TokenLogoutHandler(tokenManager,redisTemplate)).and()
                .addFilter(new TokenLoginFilter(authenticationManager(), tokenManager, redisTemplate,journalService))
                .addFilter(new TokenAuthFilter(authenticationManager(), tokenManager, redisTemplate)).httpBasic();

    }
}

这一步中的关键便是构造函数中为注入Bean赋值,然后配置Filter时注入对象即可。

好了,这样即可完成过滤器中注入Bean操作,觉得有帮助,帮小编点个赞吧!

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
5月前
|
Java 容器
如何在SpringBoot项目中使用过滤器和拦截器
过滤器和拦截器是日常开发中常用技术,用于对特定请求进行增强处理,如插入自定义代码以实现特定功能。过滤器在请求到达 `servlet` 前执行,而拦截器在请求到达 `servlet` 后执行。`SpringBoot` 中的拦截器依赖于 `SpringBoot` 容器,过滤器则由 `servlet` 提供。通过实现 `Filter` 接口并重写 `doFilter()` 方法可实现过滤器;通过实现 `HandlerInterceptor` 接口并重写相应方法可实现拦截器。两者的主要区别在于执行时机的不同,需根据具体场景选择使用。
242 4
如何在SpringBoot项目中使用过滤器和拦截器
|
6月前
|
SQL Java 测试技术
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
332 0
|
3月前
|
Java
SpringBoot构建Bean(RedisConfig + RestTemplateConfig)
SpringBoot构建Bean(RedisConfig + RestTemplateConfig)
60 2
|
3月前
|
前端开发 Java 数据格式
SpringBoot中定义Bean的几种方式
本文介绍了Spring Boot中定义Bean的多种方式,包括使用@Component、@Bean、@Configuration、@Import等注解及Java配置类。每种方式适用于不同的场景,帮助开发者高效管理和组织应用组件。
|
4月前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
4月前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
63 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
4月前
|
Java Spring 容器
Springboot3.2.1搞定了类Service和bean注解同名同类型问题修复
这篇文章讨论了在Spring Boot 3.2.1版本中,同名同类型的bean和@Service注解类之间冲突的问题得到了解决,之前版本中同名bean会相互覆盖,但不会在启动时报错,而在配置文件中设置`spring.main.allow-bean-definition-overriding=true`可以解决这个问题。
159 0
Springboot3.2.1搞定了类Service和bean注解同名同类型问题修复
|
5月前
|
Java Spring
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
本文介绍了如何在Spring Boot项目中集成Swagger 2.x和3.0版本,并提供了解决Swagger在Spring Boot中启动失败问题“Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerEx”的方法,包括配置yml文件和Spring Boot版本的降级。
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
|
4月前
|
Java Shell C++
Springboot加载注入bean的方式
本文详细介绍了Spring Boot中Bean的装配方法。首先讲解了使用@Component、@Service、@Controller、@Repository等注解声明Bean的方式,并解释了这些注解之间的关系及各自适用的层次。接着介绍了通过@Configuration和@Bean注解定义Bean的方法,展示了其灵活性和定制能力。最后讨论了@Component与@Bean的区别,并提供了在Spring Boot应用中装配依赖包中Bean的三种方法:使用@ComponentScan注解扫描指定包、使用@Import注解导入特定Bean以及在spring.factories文件中配置Bean。
142 0
|
6月前
|
缓存 Java 数据库连接
Spring Boot 资源文件属性配置,紧跟技术热点,为你的应用注入灵动活力!
【8月更文挑战第29天】在Spring Boot开发中,资源文件属性配置至关重要,它让开发者能灵活定制应用行为而不改动代码,极大提升了可维护性和扩展性。Spring Boot支持多种配置文件类型,如`application.properties`和`application.yml`,分别位于项目的resources目录下。`.properties`文件采用键值对形式,而`yml`文件则具有更清晰的层次结构,适合复杂配置。此外,Spring Boot还支持占位符引用和其他外部来源的属性值,便于不同环境下覆盖默认配置。通过合理配置,应用能快速适应各种环境与需求变化。
69 0