1

Why is passwordEncoder() defined as @Bean if its called directly as a function? Here's the example I'm talking about

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

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

https://www.baeldung.com/spring-security-registration-password-encoding-bcrypt

Or I've seen people do it on auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());

Andronicus
  • 25,419
  • 17
  • 47
  • 88
Josh
  • 49
  • 1
  • 6
  • I am not getting your question fully, do you mean to ask if we can use the `PasswordEncoder` just by calling the method, then why we need to define it as bean. – Bilbo Baggins Aug 30 '19 at 11:01
  • Yes, I dont understand why @Bean annotation is used – Josh Aug 30 '19 at 11:15

3 Answers3

2

@Bean annotation can appear over method, this is one possibility to register beans. This way BeanFactory is aware of this bean and qualifies it with name derived from method name ("passwordEncoder"). Other way would be to name them explicitly:

 @Bean({"b1", "b2"}) // bean available as 'b1' and 'b2', but not 'myBean'
 public MyBean myBean() {
     // instantiate and configure MyBean obj
     return obj;
 }

Consult the javadoc for more info.

Edit: in the example @Bean is defined to bind the abstraction PasswordEncoder to the implementation BCryptPasswordEncoder. Otherwise spring would not know, what's the concrete class if there were more of them in scan.

Andronicus
  • 25,419
  • 17
  • 47
  • 88
  • What do you mean by "to bind the abstraction PasswordEncoder to the implementation BCryptPasswordEncoder" ? – Josh Aug 30 '19 at 11:15
  • `BCryptPasswordEncoder` implements `PasswordEncoder`, but there could be another class, that does that, say `Banana` - without this definition, how would spring know what to take - `BCryptPasswordEncoder` or `Banana` if you write `@Autowired PasswordEncoder`? – Andronicus Aug 30 '19 at 11:18
  • I didn't write @Autowired PasswordEncoder, isn't passwordEncoder() just a simple function call which returns a new object of type BCryptPasswordEncoder which implements PasswordEncoder? – Josh Aug 30 '19 at 11:29
  • You can use it this way, you can also autowire. You do know about dependency injection? If you call it as a method, then you don't need it. – Andronicus Aug 30 '19 at 11:31
  • Oh yeah I see now that it is @Autowired in that example, my bad. what threw me off are these tutorials were there password encoder isnt injected its just called as a method https://www.javaguides.net/2018/09/spring-boot-spring-mvc-role-based-spring-security-jpa-thymeleaf-mysql-tutorial.html https://www.javainuse.com/spring/boot_security_jdbc_authentication_bcrypt – Josh Aug 30 '19 at 11:47
2

You need to read more about dependency injection, DI is a pattern which solves many of the problems, especially when used with Program to Interface , in this case if you don't write @Bean it would force it to create multiple instances of the BCryptPasswordEncoder every time you call the method. While if you write @Bean the instantiation and management of bean's life cycle is managed by the Spring Container, which again ensures that only single instance is created due to Singleton scope being the default one in spring. Read more on singleton pattern here.

Bilbo Baggins
  • 2,899
  • 10
  • 52
  • 77
0

@Bean annotation is used to register any object/method to the Spring container as Bean.

In your problem to use the passwordEncoder() method as a bean, it is marked with @Bean annotation so that it can be easily injected to other Objects and used.

Abhishek kumar
  • 148
  • 1
  • 2