Method annotated with @Bean is called directly – function calling a bean in a @Service class

Issue

I just get an error over and over inside the function "save" that is saying:
"Method annotated with @Bean is called directly. Use dependency injection instead."
when calling "passwordEncoder()"

in this line

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

What am I missing in the spring logic that it’s not working?

BTW – followed the tut : 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

Solution

The ‘@Bean’ annotation is telling Spring to create a new Spring Bean, using the logic in the method that it decorates.
This is usually done in Configuration classes, much like you are doing in your AuthorizationServiceConfig (https://github.com/arocketman/SpringBlog/blob/master/src/main/java/com/arocketman/github/config/AuthorizationServerConfig.java).

What you are doing here is calling the annotated method in order to fetch the Spring-managed bean. This is not allowed. How you would go about fixing this, while keeping your passwordencoder as a bean, is by autowiring the bean into this server, just like you do with the UserRepository.

So you would move the annotated method to a configuration class (either an existing or new one), and then autowire it into this Service.
Something like this:

@Autowired
private BCryptPasswordEncoder passwordEncoder;

Your ‘save’ method then becomes:

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

I hope this helps you out.
Good luck with your project!

Answered By – Stijn Dejongh

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published