Spring @Service类中直接调用@Bean标注的passwordEncoder方法报错如何解决?
问题根源
标注了@Bean的方法是用来给Spring容器注册Bean实例的,不能直接在类内部手动调用,Spring要求必须通过依赖注入的方式获取该Bean实例。另外将PasswordEncoder的@Bean定义放在@Service业务类中也不符合Spring的分层规范,@Bean通常应该定义在专门的@Configuration配置类中。
修复方案
方案1:直接注入容器中的PasswordEncoder实例(最简便)
无需调整现有@Bean的位置,只需要新增依赖注入字段,修改代码如下:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService { @Autowired private UserRepository userRepository; // 新增:注入容器中已注册的PasswordEncoder实例 @Autowired private PasswordEncoder passwordEncoder; @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } public void save(User user){ // 调整:用注入的实例调用encode方法,不再直接调用@Bean标注的passwordEncoder()方法 user.setPassword(passwordEncoder.encode(user.getPassword())); userRepository.save(user); } public User getUser(String username){ return userRepository.findByUsername(username); } public List<User> getAllUsers() { return userRepository.findAll(); } }
方案2:将PasswordEncoder的Bean定义移到配置类(规范写法,更推荐)
符合Spring的分层设计原则,避免业务类混杂配置逻辑:
- 先新建独立的安全配置类,把
PasswordEncoder的Bean定义移到该类中
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration public class SecurityConfig { @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } }
- 删除UserService里的
@Bean方法,保留注入字段即可
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService { @Autowired private UserRepository userRepository; @Autowired private PasswordEncoder passwordEncoder; public void save(User user){ user.setPassword(passwordEncoder.encode(user.getPassword())); userRepository.save(user); } public User getUser(String username){ return userRepository.findByUsername(username); } public List<User> getAllUsers() { return userRepository.findAll(); } }
内容的提问来源于stack exchange,提问作者OmerLuxon
相关产品推荐
相关产品推荐

