问题出现场景: 本地启动不会报错,服务器上启动会报错
Error creating bean with name ‘passwordEncoder’: Requested bean is currently in creation: Is there an unresolvable circular reference?
图 1
 图 2
图 2
 图 3
图 3

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