Java?SpringBoot整合shiro-spring-boot-starterqi項目報錯解決
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;
}根據(jù)異常信息查看ShiroWebAutoConfiguration源碼時發(fā)現(xiàn)其中已經(jīng)定義了securityManager方法,我們在ShiroConfig配置類中再次定義securityManager方法,因返回的類與其不一樣導致出錯,
ShiroWebAutoConfiguration類中定義的securityManager方法代碼如下:
@Bean
@ConditionalOnMissingBean
@Override
protected SessionsSecurityManager securityManager(List<Realm> realms) {
return super.securityManager(realms);
}下面這些為補充知識:我們都知道@ConditionalOnBean作用是根據(jù)value屬性按bean的類型或則bean的名稱判斷bean是否在IOC容器中,如果在就返回true,否則返回false。而@ConditionalOnMissingBean的作用與@ConditionalOnBean相反。如果@ConditionalOnBean和@ConditionalOnMissingBean這兩個注解沒有參數(shù),那這兩個注解以何種方式來判斷呢?在Spring Boot官方文檔中找出了答案。

意思是:在@ConditionalOnMissingBean沒有參數(shù)的情況下,目標類型默認為方法的返回類型,如果IOC容器中沒有類型為MyService及其子類的Bean,那么myServiceBean將被創(chuàng)建。
從源代碼中可以看出@ConditionalOnMissingBean沒有參數(shù),那么如果IOC容器中沒有類型為SessionsSecurityManager及其子類的Bean,那么該方法則會執(zhí)行,并且源碼securityManager方法返回的是SessionsSecurityManager,而自己定義的ShiroConfig中返回的是SecurityManager(因為@Bean注解會指定改bean的類型為該方法的返回類型),所以它會判斷出IOC容器中沒有類型為SessionsSecurityManager及其子類的Bean,源碼中的方法執(zhí)行,故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
//掃描下面的接口生成代理實現(xiàn)類
@MapperScan("com.ncwu.**.domain.mapper")
public class ShiroApplication {
public static void main(String[] args) {
SpringApplication.run(ShiroApplication.class, args);
}
//若IOC容器中沒有Animal類型及其子類Dog類型的bean時,該方法才會執(zhí)行
@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 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring?Boot在Web應用中基于JdbcRealm安全驗證過程
這篇文章主要為大家介紹了Spring?Boot在Web應用中基于JdbcRealm安全驗證過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪<BR>2023-02-02
關于shiro中部分SpringCache失效問題的解決方法
這篇文章主要給大家介紹了關于shiro中部分SpringCache失效問題的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-07-07
Java web實現(xiàn)賬號單一登錄,防止同一賬號重復登錄(踢人效果)
這篇文章主要介紹了Java web實現(xiàn)賬號單一登錄,防止同一賬號重復登錄,有點類似于qq登錄踢人效果,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-10-10
Java橋梁設計模式優(yōu)雅地將抽象與實現(xiàn)分離
Java橋接設計模式通過將抽象和實現(xiàn)分離,使得它們可以獨立地變化,從而實現(xiàn)更靈活的代碼結構。它是一種優(yōu)雅的設計模式,適用于需要處理多個變化因素的復雜應用程序2023-04-04

