【问题标题】:Method annotated with @Bean is called directly - function calling a bean in a @Service class直接调用@Bean注解的方法——函数调用@Service类中的一个bean
【发布时间】:2021-09-02 17:21:15
【问题描述】:

我只是在“保存”函数中一遍又一遍地得到一个错误,它说: “直接调用带有@Bean注解的方法。改用依赖注入。” 调用“passwordEncoder()”时

在这一行

user.setPassword(passwordEncoder().encode(user.getPassword()));


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;

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

    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();
    }
}

我在 spring 逻辑中遗漏了什么,它不起作用?

顺便说一句 - 紧随其后:https://www.youtube.com/watch?v=IOgCMtYMr2Q&t=1s&ab_channel=RocketMan

https://github.com/arocketman/SpringBlog/blob/master/src/main/java/com/arocketman/github/service/UserService.java

【问题讨论】:

  • 检查this
  • @Configuration 类中的@Bean 方法不像@Configuration 类中那样被代理/处理。将该方法移到您的安全配置中,然后注入 bean。

标签: java spring spring-boot


【解决方案1】:

BCryptPasswordEncoder 不是 bean,你不能自动装配它。

使用:

new BCryptPasswordEncoder().encode(user.getPassword());

或者,您可以在配置中创建这样的 bean(@Configuration):

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

然后,将其自动连接到您的服务中:

@Autowired
private PasswordEncoder passwordEncoder;

【讨论】:

  • 虽然消除了错误,但它并不能解决实际问题,您也不应该每次都重新创建 BCryptPasswordEncoder,因为它的构造非常繁重。
【解决方案2】:

'@Bean' 注释告诉 Spring 创建一个新的 Spring Bean,使用它装饰的方法中的逻辑。 这通常在配置类中完成,就像您在 AuthorizationServiceConfig (https://github.com/arocketman/SpringBlog/blob/master/src/main/java/com/arocketman/github/config/AuthorizationServerConfig.java) 中所做的一样。

您在这里所做的是调用带注释的方法以获取 Spring 管理的 bean。这是不允许的。您将如何解决此问题,同时将密码编码器保留为 bean,方法是将 bean 自动装配到此服务器中,就像您对 UserRepository 所做的那样。

因此,您可以将带注释的方法移动到配置类(现有的或新的),然后将其自动装配到此服务中。 像这样的:

@Autowired
private BCryptPasswordEncoder passwordEncoder;

你的“保存”方法就变成了:

 public void save(User user){
    user.setPassword(passwordEncoder.encode(user.getPassword()));
    userRepository.save(user);
}

我希望这对您有所帮助。 祝你的项目好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多