问题出现场景: 本地启动不会报错,服务器上启动会报错
Error creating bean with name ‘passwordEncoder’: Requested bean is currently in creation: Is there an unresolvable circular reference?
图 1 图 2 图 3
问题 1
:SpringIOC 是不是通过 @ComponentScan 去把扫描到的相关带有注解的类注入到 Bean 中吗?问题 2
:继续上个问题(见图 2 ),注入顺序我说的是否正确?
扣题
:如果我想解决上述代码导致的循环依赖,我并不想使用 new 一个 PasswordEncoder 的方式(见图 3 )解决循环依赖,有没有更优雅的办法?
1
SoulSleep 2020-05-21 08:31:46 +08:00
现在版本的 Spring 不会在日志里打印出你循环依赖的三个类吗?
如果你本地启动没问题,那大概就是加载顺序的问题了 循环依赖我感觉有两种办法: 1.检查你的引用是否有 jar 冲突,jar 的加载顺序改变了 bean 初始化的顺序 2.使用 @DependOn 去指定 bean 加载顺序 |
2
Dachunlv 2020-05-21 08:36:42 +08:00 1
出现循环依赖大多数情况说明逻辑设计上就出了问题,可以尝试调整设计本身,否则治标不治本。比如创建中间代理 Bean ?
|
3
luckyrayyy 2020-05-21 08:39:01 +08:00
懒加载一个
|
4
luckyrayyy 2020-05-21 08:41:53 +08:00
或者你只从一个地方注入,另一个地方把已经注入的 bean 以构造器参数 /setter 的方式传过去
|
5
xuanbg 2020-05-21 08:43:38 +08:00
循环依赖就是典型的「代码写错了地方」。解决这个问题也很简单,把写错地方的代码挪到正确的地方就行。如楼主的例子,就是把 passwordEncode 这个方法从 WebSecurityConfig 拿出来单独一个类就行了
|
7
quarria 2020-05-21 08:57:17 +08:00
我也出现过这问题,原来 springboot2.0.3 的时候一点问题没有,升级到 2.2.6 就出现了这问题。第一种方法是在互相能循环调用的类上加懒加载的注解。第二种方法是实现 BeanFactoryPostProcessor 这个类中的 postProcessBeanFactory 方法。方法内写((AbstractAutowireCapableBeanFactory) beanFactory).setAllowRawInjectionDespiteWrapping(true); 这样就可以启动不报错了,但治标不治本,最终还是优化代码,尽量解耦,不出现循环调用的问题。
|
8
xiaofan2 2020-05-21 09:02:16 +08:00
setter 注入能产生循环依赖吗? 你的 PasswordEncoder 是自建的还是什么
|
9
aragakiyuii 2020-05-21 09:02:45 +08:00 via Android
再包一层
官方推荐用构造函数注入而非注解注入 |
10
yRebelHero 2020-05-21 09:09:53 +08:00
试试用 @Lazy ?不过一般这样就是设计出问题了。
|
11
linuxsteam OP |
13
szuwl 2020-05-21 09:13:14 +08:00
1. 懒加载
2. 重构(更改设计) |
14
linuxsteam OP @quarria 是的。你的那种做法,我在百度搜到了。但是无奈还得加代码(那个实现的类我还不了解,就放弃了)
|
15
linuxsteam OP @xiaofan2 springsecurity 自带的。
|
16
Jrue0011 2020-05-21 09:43:17 +08:00
应该是不在 WebSecurityConfig 里注册 passwordEncoder,另外找个地方注册就行
|
17
cco 2020-05-21 10:00:09 +08:00
构造器注入就可以。
|
18
pomelotea2009 2020-05-21 12:53:05 +08:00 via Android
@Dachunlv 赞同,最简单的比如服务 A&B 循环依赖,你可以把服务 B 里对服务 A 的调用,挪到控制器里去做,在控制器里调用服务 A 之后,结果传参调用服务 B,原则上服务 A 和 B 也应该尽量隔离,除了一些小的工具服务
|
19
Chinsung 2020-05-21 17:43:46 +08:00
之前遇到过,首先逻辑最好理清楚,确实会有这样的问题,本地可以,服务器不行,如果实在不想大调整,或者 DependsOn 注解解决不了问题,可以把报错的那个类的 spring 配置类的包结构深度来改变顺序,我之前就是这么解决的
|
20
linuxsteam OP @Chinsung 那就是说 浅的优先注入呗? 如果这样就行,这个适合懒人啊
|