0

This is actually a part of the question that I asked here, which went unanswered and ended up being tagged as duplicate.

Issue : I am able to use the JavaMailSender just by annotating it with @Autowired. I didn't expose it through any configuration class.

@Component
    public class EmailUtil {

        @Autowired
        private JavaMailSender javaMailSender;

    }

However, the below doesn't work unless BCryptPasswordEncoder bean is exposed via a configuration class.

@Controller
        public class UserController {   

            @Autowired
            private BCryptPasswordEncoder encoder;

    }

I'm using Spring Boot 1.5.8

My doubts are:

  • why JavaMailSender " was successfully injected, whereas the BCryptPasswordEncoder /PasswordEncoder autowiring was successful only after exposing it via a configuration class.

  • How do I know for sure when to expose beans explicitly via a configuration class and when not to ? How do I know which beans need to be exposed ?

Any sort of help/guidance is highly appreciated.

Asif Kamran Malick
  • 2,409
  • 3
  • 25
  • 47

1 Answers1

2

Basically, an implementation of JavaMailSender is exposed as part of the Spring Boot Autoconfiguration. This is noted in the documentation here:

The Spring Framework provides an easy abstraction for sending email by using the JavaMailSender interface, and Spring Boot provides auto-configuration for it as well as a starter module.

This is not the case with BCryptPasswordEncoder.

If I had to guess, I would think that this approach was chosen because:

  • Few developers would need to reimplement the JavaMailSender functionality for sending Emails
  • Many developers choose different hashing algorithms based on speed and security needs, though the BCryptPasswordEncoder is recommended.
  • Since various developers might opt for an alternative PasswordEncoder, having a BCryptPasswordEncoder already configured would necessitate using @Primary on the one you actually wanted to use (in the case of writing something like @Autowired PasswordEncoder encoder), which might lead to confusion.

How do I know for sure when to expose beans explicitly via a configuration class and when not to ? How do I know which beans need to be exposed ?

Read the reference documentation for the particular bean - it should state whether it is pre-configured or not (and under which conditions, i.e. in the presence of some starter package). Barring that, you might check the implementation to see if there are any components which implement the interface of the bean you wish to inject.

UPDATE: I actually went through some of the sources and noticed that the interfaces implemented by BCryptPasswordEncoder on one hand, and Md5PasswordEncoder/ShaPasswordEncoder on the other, are in different packages, the latter being deprecated. In this case it may be safe to assume that there is no autoconfiguration being done for BCryptPasswordEncoder since:

  1. It could lead to a great deal of confusion to see one interface be implemented, when a completely different one in a different package is being referred to (i.e. different methods being implemented)
  2. The 'default values' that should be used when hashing a password would likely differ from one developer to another, which would necessitate manual configuration anyway.
filpa
  • 3,651
  • 8
  • 52
  • 91
  • Thanks for clarifying this. The mailsender is indeed getting autoconfigured. I tried to print out the names of the configured beans and it did confirm that. Here are the mail related dependencies that were autoconfigured : **1.** `org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration` **2.**`mailSender` **and** **3.** `spring.mail-org.springframework.boot.autoconfigure.mail.MailProperties`. The secondnd one proves that MailSender was indeed autowired. Will save your words for future reference. This answers my query. – Asif Kamran Malick Apr 19 '18 at 21:19
  • user991710 Just to add: I did go through the section 17 of the documentation to get any hint, but no luck. Thanks a lot for directing me to the exact section. – Asif Kamran Malick Apr 19 '18 at 21:26