Java SpringBoot整合shiro-spring-boot-starterqi项目报错解决

 更新时间:2022年8月12日 15:50  点击:469 作者:静水楼台x

1、项目启动时报错如下

Description:
The bean 'securityManager', defined in class path resource [org/apache/shiro/spring/config/web/autoconfigure/ShiroWebAutoConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [com/ncwu/common/infrastructure/config/ShiroConfig.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

2、原因分析

我的自定义ShiroConfig配置类中添加的安全管理器,

代码如下:

@Bean
public SecurityManager securityManager(JwtRealm jwtRealm) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    //配置realm
    securityManager.setRealm(jwtRealm);
    return securityManager;
}

 根据异常信息查看ShiroWebAutoConfiguration源码时发现其中已经定义了securityManager方法,我们在ShiroConfig配置类中再次定义securityManager方法,因返回的类与其不一样导致出错,

ShiroWebAutoConfiguration类中定义的securityManager方法代码如下:

@Bean
@ConditionalOnMissingBean
@Override
protected SessionsSecurityManager securityManager(List<Realm> realms) {
    return super.securityManager(realms);
}

下面这些为补充知识:我们都知道@ConditionalOnBean作用是根据value属性按bean的类型或则bean的名称判断bean是否在IOC容器中,如果在就返回true,否则返回false。而@ConditionalOnMissingBean的作用与@ConditionalOnBean相反。如果@ConditionalOnBean和@ConditionalOnMissingBean这两个注解没有参数,那这两个注解以何种方式来判断呢?在Spring Boot官方文档中找出了答案。

意思是:在@ConditionalOnMissingBean没有参数的情况下,目标类型默认为方法的返回类型,如果IOC容器中没有类型为MyService及其子类的Bean,那么myServiceBean将被创建。

从源代码中可以看出@ConditionalOnMissingBean没有参数,那么如果IOC容器中没有类型为SessionsSecurityManager及其子类的Bean,那么该方法则会执行,并且源码securityManager方法返回的是SessionsSecurityManager,而自己定义的ShiroConfig中返回的是SecurityManager(因为@Bean注解会指定改bean的类型为该方法的返回类型),所以它会判断出IOC容器中没有类型为SessionsSecurityManager及其子类的Bean,源码中的方法执行,故IOC容器中有两个名为securityManager的Bean,因而报错。所以如果要自定义securityManager方法,返回类型只能是SessionsSecurityManager及其子类,而SessionsSecurityManager的子类是DefaultSecurityManager,DefaultWebSecurityManager又继承DefaultSecurityManager,

相关类图如下:

故而正确的代码应该是:

@Bean
public SessionsSecurityManager securityManager(JwtRealm jwtRealm) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    //配置realm
    securityManager.setRealm(jwtRealm);
    return securityManager;
}
 
//或者如下,将方法返回类型改为DefaultWebSecurityManager 
/*@Bean
public DefaultWebSecurityManager securityManager(JwtRealm jwtRealm) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    //配置realm
    securityManager.setRealm(jwtRealm);
    return securityManager;
}*/

3、测试@ConditionalOnMissingBean注解

新建下面3个类:

//动物
@Data
public class Animal {
    private String name;
    private Integer age;
}

//狗
@EqualsAndHashCode(callSuper = true)
@Data
public class Dog extends Animal {
    private String type;
}
 
//二哈
@EqualsAndHashCode(callSuper = true)
@Data
public class TwoHa extends Dog {
    private String a;
}

启动类:

@SpringBootApplication
//扫描下面的接口生成代理实现类
@MapperScan("com.ncwu.**.domain.mapper")
public class ShiroApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShiroApplication.class, args);
    }

    //若IOC容器中没有Animal类型及其子类Dog类型的bean时,该方法才会执行
    @Bean
    @ConditionalOnMissingBean
    public Animal twoHa(JwtRealm realm) {
        TwoHa twoHa = new TwoHa();
        twoHa.setType("twoHa1");
        twoHa.setAge(10);
        twoHa.setName("twoHa1");
        return twoHa;
    }

    @Bean
    public Dog twoHa() {
        TwoHa twoHa = new TwoHa();
        twoHa.setType("twoHa2");
        twoHa.setAge(20);
        twoHa.setName("twoHa2");
        return twoHa;
    }
}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ShiroApplication.class)
public class TestDao {
    @Autowired
    private ApplicationContext appContext;
    @Test
    public void test() throws Exception{
        /*String[] beanNamesForType = appContext.getBeanNamesForType(Animal.class);
        for (String s : beanNamesForType) {
            System.out.println(s);
        }*/
        appContext.getBean(Animal.class);
        //appContext.getBean("dog");
    }
}

测试结果:

到此这篇关于Java SpringBoot整合shiro-spring-boot-starterqi项目报错解决的文章就介绍到这了,更多相关Java SpringBoot 内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://blog.csdn.net/xiyafei122/article/details/126294489

[!--infotagslink--]

相关文章

  • Java实现经典游戏复杂迷宫

    这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
  • java 运行报错has been compiled by a more recent version of the Java Runtime

    java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01
  • 在java中获取List集合中最大的日期时间操作

    这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
  • Spring AOP 对象内部方法间的嵌套调用方式

    这篇文章主要介绍了Spring AOP 对象内部方法间的嵌套调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
  • 解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题

    这篇文章主要介绍了解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-28
  • Spring Cloud 中@FeignClient注解中的contextId属性详解

    这篇文章主要介绍了Spring Cloud 中@FeignClient注解中的contextId属性详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-25
  • Springboot如何实现Web系统License授权认证

    这篇文章主要介绍了Springboot如何实现Web系统License授权认证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-28
  • 教你怎么用Java获取国家法定节假日

    这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
  • Java如何发起http请求的实现(GET/POST)

    这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
  • 浅谈Java与C#的一些细微差别

    说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
  • SpringBoot实现excel文件生成和下载

    这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
  • 解决Java处理HTTP请求超时的问题

    这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
  • 如何在Spring WebFlux的任何地方获取Request对象

    这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26
  • 详解springBoot启动时找不到或无法加载主类解决办法

    这篇文章主要介绍了详解springBoot启动时找不到或无法加载主类解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-16
  • java 判断两个时间段是否重叠的案例

    这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
  • 详解SpringCloudGateway内存泄漏问题

    这篇文章主要介绍了详解SpringCloudGateway内存泄漏问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-16
  • 超简洁java实现双色球若干注随机号码生成(实例代码)

    这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
  • SpringBoot集成Redis实现消息队列的方法

    这篇文章主要介绍了SpringBoot集成Redis实现消息队列的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-10
  • Java生成随机姓名、性别和年龄的实现示例

    这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
  • java 画pdf用itext调整表格宽度、自定义各个列宽的方法

    这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31