You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已配置PasswordEncoder Bean仍报错:Spring Security无法找到该Bean

问题:Spring Security中已定义PasswordEncoder Bean但启动报错

我正在用Spring Security和JWT实现API认证,注册功能里用PasswordEncoder加密密码。已经在AppConfig配置类中定义了PasswordEncoder类型的Bean,但启动应用时出现以下错误:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 1 of constructor in com.akuntansi.akuntansi.repo.AuthenticationService required a bean of type 'org.springframework.security.crypto.password.PasswordEncoder' that could not be found.


Action:

Consider defining a bean of type 'org.springframework.security.crypto.password.PasswordEncoder' in your configuration.

配置类代码(AppConfig)

package com.akuntansi.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import com.akuntansi.akuntansi.repo.UserRepo;

import lombok.RequiredArgsConstructor;

@Configuration
@RequiredArgsConstructor
public class AppConfig {

    private final UserRepo userRepo;

    @Bean
    public UserDetailsService userDetailsService(){
        return username -> userRepo.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("User not found!"));
    }

    @Bean
    public AuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService());
        authProvider.setPasswordEncoder(passwordEncoder());

        return authProvider;
    }
    
    @Bean
     public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception{
        return config.getAuthenticationManager();
    }
}

AuthenticationService类代码

package com.akuntansi.akuntansi.repo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.akuntansi.akuntansi.model.Role;
import com.akuntansi.akuntansi.model.Users;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class AuthenticationService {
    
private final UserRepo userRepo;
private final PasswordEncoder passwordEncoder;
private final JWTService jwtService;
private final AuthenticationManager authenticationManager;

    public AuthenticationResponse register(RegisterRequest request){
        var user =  Users.builder()
                    .username(request.getUsername())
                    .password(passwordEncoder.encode(request.getPassword()))
                    .role(Role.USER)
                    .build();
                    
        userRepo.save(user);
        var jwtToken = jwtService.generateJwtToken(user);

        return AuthenticationResponse.builder()
                .token(jwtToken) 
                .build();
    }

    public AuthenticationResponse login(AuthenticationRequest request){
        authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(
                request.getUsername(),
                request.getPassword()
            )
        );
        var user = userRepo.findByUsername(request.getUsername()).orElseThrow();
        var jwtToken = jwtService.generateJwtToken(user);
        return AuthenticationResponse.builder()
                .token(jwtToken)
                .build();
    }
}

问题原因及解决方案

核心原因

Spring容器没有扫描到你的AppConfig配置类,导致其中定义的PasswordEncoder Bean未被注册,而AuthenticationService依赖该Bean,因此启动时报错。

从包结构来看:

  • AppConfig在com.akuntansi.config包
  • AuthenticationService在com.akuntansi.akuntansi.repo包

Spring默认组件扫描范围是主启动类所在包及其子包,如果主启动类在com.akuntansi.akuntansi下,com.akuntansi.config不在默认扫描范围内,AppConfig不会被加载。

解决方案

方案1:扩展组件扫描范围

在Spring Boot主启动类上添加@ComponentScan注解,指定根扫描包,确保包含com.akuntansi.config:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = {"com.akuntansi"})
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

方案2:调整配置类位置

将AppConfig移动到主启动类所在包或其子包下,比如主启动类在com.akuntansi.akuntansi,就把AppConfig移到com.akuntansi.akuntansi.config包中,让Spring默认扫描覆盖到。

额外检查

确保项目已引入Spring Security依赖,比如Maven的spring-boot-starter-security,依赖缺失也会导致相关Bean无法正常注册。

内容的提问来源于stack exchange,提问作者Timothy Justin William

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 14:37:55