springboot1.X和2.X中怎么解决Bean名字相同时覆盖


这篇文章主要介绍“springboot1.X和2.X中怎么解决Bean名字相同时覆盖”,在日常操作中,相信很多人在springboot1.X和2.X中怎么解决Bean名字相同时覆盖问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”springboot1.X和2.X中怎么解决Bean名字相同时覆盖”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!在2版本之前的版本,项目中有两个相同名字的bean是可以启动成功的,但是会有覆盖问题但是在2.X版本的时候会报错:could not be registered. A bean with that name has already been defined in class path resource这时候解决办法可以在配置文件中添加:Defaultis”true”.【这里明确说明了默认是true】
*@see#registerBeanDefinition
*/
publicbooleanisAllowBeanDefinitionOverriding(){
returnthis.allowBeanDefinitionOverriding;
}

@Override
publicvoidregisterBeanDefinition(StringbeanName,BeanDefinitionbeanDefinition)
throwsBeanDefinitionStoreException{

Assert.hasText(beanName,”Beannamemustnotbeempty”);
Assert.notNull(beanDefinition,”BeanDefinitionmustnotbenull”);

if(beanDefinitionins免费云主机域名tanceofAbstractBeanDefinition){
try{
((AbstractBeanDefinition)beanDefinition).validate();
}
catch(BeanDefinitionValidationExceptionex){
thrownewBeanDefinitionStoreException(beanDefinition.getResourceDescription(),beanName,
“Validationofbeandefinitionfailed”,ex);
}
}

//bean加载到spring的工程中后,会存储在beanDefinitionMap中,key是bean的名称。
BeanDefinitionexistingDefinition=this.beanDefinitionMap.get(beanName);
if(existingDefinition!=null){//不为空,说明相同名称的bean已经存在了
if(!isAllowBeanDefinitionOverriding()){//如果不允许相同名称的bean存在,则直接抛出异常
thrownewBeanDefinitionOverrideException(beanName,beanDefinition,existingDefinition);
}
elseif(existingDefinition.getRole()updatedDefinitions=newArrayList(this.beanDefinitionNames.size()+1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames=updatedDefinitions;
if(this.manualSingletonNames.contains(beanName)){
SetupdatedSingletons=newLinkedHashSet(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames=updatedSingletons;
}
}
}
else{
//Stillinstartupregistrationphase
this.beanDefinitionMap.put(beanName,beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames=null;
}

if(existingDefinition!=null||containsSingleton(beanName)){
resetBeanDefinition(beanName);
}
}上面贴出来的是spring的代码,而springboot2.X对这个参数又进行了二次封装,springboot中的allowBeanDefinitionOverriding是没有初始化默认值的,我们知道,java中的boolean类型不初始化时是false。springboot中源代码:在SpringApplication类中而在1.5.8版本中,SpringApplication中,没有allowBeanDefinitionOverriding属性,因此在prepareContext方法中也就没有对allowBeanDefinitionOverriding进行赋值为false,所以在springboot1.5.8版本中默认就是支持名称相同的bean的覆盖。什么情况下要覆写原有的Spring Bean ? 例如引入的第三方jar包中的某个类有些问题,然有没有源码提供或者嫌编译源码太费事,这个时间可以考虑覆写原有的类。方式简单粗暴,可以直接覆盖掉jar包中的类,spring项目会优先加载自定义的类。下面是覆盖 flowable框架中的一个类 FlowableCookieFilter,主要是想修改它里面的redirectToLogin方法的业务逻辑。包路径为 org.flowable.ui.common.filter, 直接工程里面新建一样路径一样类名FlowableCookieFilter即可。方法2 采用@Primary注解该方法适用于接口实现类,自己创建一个原jar包接口的实现类,然后类上加上@Primary注解,spring则默认加载该类实例化出的Bean。下面的例子: 一个接口 RemoteIdmService,原先jar包中只有一个实现类 RemoteIdmServiceImpl,现在自己工程里面创建一个 CustomRemoteIdmServiceImpl 继承RemoteIdmService接口,然后发现所有调用RemoteIdmService接口里面的方法实际调用走的是CustomRemoteIdmServiceImpl 里面的方法。使用 @ComponentScan 里面的 excludeFilters 功能排除调用要替换的类,然后自己写个类继承替换的类即可。下面的例子是替换掉 jar包中的PersistentTokenServiceImpl类该场景针对,框架jar包中有@ConditionalOnMissingBean注解,这种注解是说明如果你也创建了一个一样的Bean则框架就不自己再次创建这个bean了,这样你可以覆写自己的bean。原jar包中的配置类:直接继承要覆盖的类,自己重写里面方法,使用@Component注入到spring中去关于 BeanDefinitionRegistryPostProcessor 、 BeanFactoryPostProcessor可以参考这篇文章:BeanDefinitionRegistryPostProcessor 说白了就是可以在初始化Bean之前修改Bean的属性,甚至替换原先准备要实例化的bean。实战演示:假设jar包中有一个类 MyTestService,正常情况下它会被spring自动扫描到注入IOC容器中去。自己工程中继承该类,并且覆写里面的show中的方法然后 实现 BeanDefinitionRegistryPostProcessor 接口,修改原来bean定义,主要查看postProcessBeanDefinitionRegistry方法的实现,先清空原bean定义,注册我们自己的bean定义来达到替换的目的。写一个 业务类BusinessTestService测试一下,期望结果:所有用到 MyTestService的地方实际调用的变成了MyTestServiceIpml里面的方法。控制台打印如下:可以发现,和我们期望的结果的一样:所有用到 MyTestService的地方实际调用的变成了MyTestServiceIpml里面的方法 !到此,关于“springboot1.X和2.X中怎么解决Bean名字相同时覆盖”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注百云主机网站,小编会继续努力为大家带来更多实用的文章!

相关推荐: 怎么用Python打造一个语音合成系统

今天小编给大家分享一下怎么用Python打造一个语音合成系统的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。 其实就是一个基于语音合成的工具,但是…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 07/20 16:35
Next 07/20 16:35

相关推荐