SpringBoot项目存在对应Bean但@Autowired依赖注入为空问题求助
问题根因
你遇到的注入失败问题是Spring Bean初始化顺序的特性导致的:
你当前使用的是字段注入,Spring对Bean的初始化遵循固定流程:
- 调用类的构造方法完成对象实例化
- 实例化完成后,才会将@Autowired标注的依赖注入到对应的字段中
因此你在构造方法中访问@Autowired标注的defaultPasswordEncoder字段时,字段注入动作尚未执行,即使你通过@DependsOn保证了defaultPasswordEncoderBean已经提前创建完成,也只会将该Bean保存在Spring容器中,还没有赋值到当前Encoders实例的对应字段上,所以读取结果为null。
解决方案
有两种常用的方式可以解决该问题:
方案1:使用构造器注入(Spring官方优先推荐)
将需要的依赖直接作为构造方法的参数,Spring在调用构造方法实例化Bean时,会自动将容器中已创建好的依赖Bean作为参数传入,你可以直接在构造方法中使用该参数:
@Component public class Encoders { private static PasswordEncoder bCryptPasswordEncoder; // 直接将PasswordEncoder声明为构造参数,Spring会自动注入 public Encoders(PasswordEncoder defaultPasswordEncoder) throws UnsupportedEncodingException { System.out.println("\n\n\n " + (defaultPasswordEncoder == null) + " \n\n\n"); Encoders.bCryptPasswordEncoder = defaultPasswordEncoder; } // 其他方法 }
Spring 4.3及以上版本中,如果类只有一个构造方法,参数对应的依赖会自动注入,不需要额外添加@Autowired注解。
方案2:使用@PostConstruct执行初始化逻辑
如果你不想修改现有构造方法的定义,可以把依赖注入完成后才需要执行的初始化逻辑放到@PostConstruct标注的方法中,该方法会在所有字段注入完成后自动触发:
@Component public class Encoders { private static PasswordEncoder bCryptPasswordEncoder; @Autowired private PasswordEncoder defaultPasswordEncoder; public Encoders() throws UnsupportedEncodingException { // 构造方法中不要访问未注入的字段 } @PostConstruct private void init() { System.out.println("\n\n\n " + (defaultPasswordEncoder == null) + " \n\n\n"); Encoders.bCryptPasswordEncoder = defaultPasswordEncoder; } // 其他方法 }
注意:以上两种方案都不需要额外添加@DependsOn注解,Spring会自动根据依赖关系调整Bean的创建顺序。
内容的提问来源于stack exchange,提问作者Seema Sharma
相关产品推荐
相关产品推荐

