Spring 整合 Shiro 的过程中出现的问题(一)

Spring 整合 Shiro 的过程中出现的问题(一)

Spring 版本:由 Spring Boot 整合,版本为 2.6.2

Shiro 版本:1.8.0


问题描述

当通过自定义 ShiroFilterChainDefinition Bean来过滤相关的请求时,定义的配置类内容如下所示:

package org.xhliu.demo.config;

import org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration;
import org.apache.shiro.spring.config.ShiroBeanConfiguration;
import org.apache.shiro.spring.web.config.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({
    ShiroBeanConfiguration.class,
    ShiroAnnotationProcessorConfiguration.class,
    ShiroWebConfiguration.class,
    ShiroWebFilterConfiguration.class,
    ShiroRequestMappingConfig.class
})
public class ShiroWebConfig {
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();

        // 进入到 /admin 路径的请求必须具有 'admin' 的角色
        chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");

        // 进入到 /docs 路径的用户必须具有读取权限
        chainDefinition.addPathDefinition("/docs/**", "authc, perms[document:read]");

        // 所有 /user 的请求都必须经过认证
        chainDefinition.addPathDefinition("/user", "authc");

        // 对于 /tmp 的请求可以是匿名的(即不需要经过认证)
        chainDefinition.addPathDefinition("/tmp", "anon");

        return chainDefinition;
    }
}

遇到如下的问题:

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'subjectDAO' defined in class path resource [org/apache/shiro/spring/web/config/ShiroWebConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.apache.shiro.spring.web.config.ShiroWebConfiguration; factoryMethodName=subjectDAO; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/apache/shiro/spring/web/config/ShiroWebConfiguration.class]] for bean 'subjectDAO': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.apache.shiro.spring.config.ShiroConfiguration; factoryMethodName=subjectDAO; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/apache/shiro/spring/config/ShiroConfiguration.class]] bound.

The bean 'subjectDAO', defined in class path resource [org/apache/shiro/spring/web/config/ShiroWebConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/apache/shiro/spring/config/ShiroConfiguration.class] and overriding is disabled.

问题分析

这是由于在 ShiroWebConfiguration 配置 Bean 中已经预先定义了 ShiroFilterChainDefinition 类型的 Bean,在定义了自定义的 ShiroFilterChainDefinition Bean 之后,此时 Spring 容器中已经存在了两个 ShiroFilterChainDefinition 类型的 Bean,因此在注入 ShiroFilterChainDefinition 类型的 Bean 时不知道注入哪一个具体实现类,从而抛出了一个异常

这个问题一般发生在 Spring 版本较高的情况下


解决方案

通过在 application.peopertiesapplication.yml 配置文件中将 spring.main.allow-bean-definition-overriding 设置为 true,即允许 Bean 覆盖,使得自定义的 ShiroFilterChainDefinition 覆盖预先定义的 Bean,从而使得自定义的 ShiroFilterChainDefinition Bean 生效

具体配置内容如下:

spring:
  main:
    allow-bean-definition-overriding: true
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值