SpringBoot2基于重复创建bean的问题及解决
SpringBoot2重复创建bean的解决
今天在跑程序的时候报了一个重复创建事务的异常:
***************************
APPLICATION FAILED TO START
***************************Description:
The bean ‘org.springframework.transaction.config.internalTransactionAdvisor’, defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class], could not be registered. A bean with that name has already been defined and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
是ProxyTransactionManagementConfiguration.class这个bean在创建时重复了,springboot的自动装配和我的程序同时创建了相同类型的bean。
之所以报这个异常是因为在Spring2中增加了防止bean重复覆盖的策略,如果有重复则会直接报出异常,而不是像从前一样默默覆盖,导致你的bean被莫名替换,难以排查问题。
stackoverflow上的解答如下:
我这边程序的解决方案是忽略spring的自动装配,禁止TransactionAutoConfiguration即可:
@SpringBootApplication(exclude = TransactionAutoConfiguration.class)
Spring注入Bean细节--解决Bean名称重复问题
问题描述:
org.springframework.context.annotation.ConflictingBeanDefinitionException
问题原因:
在使用注解配置Bean的过程中,存在名称相同的情况,导致项目启动失败
解决办法
1)在配置实例化注解时,指定别名
在mapper中使用@Repository注解来指定别名
//项目其他包中也存在相同的类名称DepartmentMapper,这里使用value来指定别名 //正常情况下,因为配置文件中已经配置了mapper包的扫描,所以可以省略@Repository注解,如果发生上述冲突,考虑使用别名来解决 @Repository(value="DepartmentMapper2") public interface DepartmentMapper { //此处省略各种CRUD方法 }
2)在Service中指定所依赖的mapper
//这里也指定了service的别名 @Service(value="DepartmentService2") public class DepartmentServiceImpl implements DepartmentService{ //这里指定依赖哪一个Mapper,默认情况下使用ByName按类名来指定 @Resource(name="DepartmentMapper2") private DepartmentMapper departmentMapper; //省略各种service方法 }
如果service的类名也冲突了怎么办?
在service中,使用@Service配置在实现类上,如果指定别名,可以利用value属性来指定,另外,@Service中默认括号中的字符串即是value的值,所以value可以省略
@Service("DepartmentService2")
对应Controller
@Resource(name="DepartmentService2") private DepartmentService departmentService;
心得
在配置Bean的过程中所指定的别名相当于以往XML中Bean属性id的值
<bean id="beanname" class="xxx.xxx.Xxx"></bean>
再复习@Resource这个注解
//@Resource注入顺序: 1.同时指定name和type,那么按照byname和bytype匹配唯一符合条件的bean装配 // 2.指定name或者type,则按照指定方式匹配,默认按name匹配,一旦指定type则不再使用属性名匹配 // 3.如果都不指定,则按照属性名(属性名为类名首字母小写)匹配,如果没有匹配到,按照属性数据类型匹配 // 以上不匹配则抛出异常 //@Resource 默认按照ByName注入Bean //也就是寻找id为“DepartmentService”的Bean @Resource private DepartmentService departmentService; //所以可以指定name属性来改变默认规则 //这样就寻找id为“DepartmentService2”的Bean @Resource(name="DepartmentService2") private DepartmentService departmentService; //也可以那个指定class来使用ByType注入 @Resource(type=DepartmentService.class) private DepartmentService departmentService; //注意import时要导正确的包
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
MybatisPlus使用Mybatis的XML的动态SQL的功能实现多表查询
本文主要介绍了MybatisPlus使用Mybatis的XML的动态SQL的功能实现多表查询,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2023-11-11Java并发源码分析ConcurrentHashMap线程集合
这篇文章主要为大家介绍了Java并发源码分析ConcurrentHashMap线程集合,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-02-02Spring MVC 拦截器 interceptor 用法详解
这篇文章主要介绍了Spring MVC 拦截器 interceptor 用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-07-07
最新评论