Spring MailSender (SMTP)

June·2022년 7월 14일
0

우테코

목록 보기
60/84

사용법

구글 이메일을 이용해서 메일을 보내자. 5월 30일부터 기존의 보안 단계로는 연결이 되지 않는다.

2022 년 5월 30일부터 적용된 구글 보안 정책

위에서 앱 비밀번호를 누르면 16자리 비밀번호를 생성해준다. 그걸 따로 저장해두면 된다.

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=<login user to smtp server>
spring.mail.password=<login password to smtp server>
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

MailSender 인터페이스를 JavaMailSender가 상속 받는다.
구현체는 JavaMailSenderImpl이다.

EmailSender

public interface EmailSender {

    void send(String email, String authCode);
}

나중에 구현체가 바뀔 수 있으니 이메일을 보내주는 구현체를 만든다.

EmailSenderImpl

@Component
public class EmailSenderImpl implements EmailSender {

    private final MailProperties properties;
    private final JavaMailSender javaMailSender;
    
    public EmailSenderImpl(MailProperties properties,
                           JavaMailSender javaMailSender) {
        this.properties = properties;
        this.javaMailSender = javaMailSender;
    }

    @Override
    public void send(String email, String authCode) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(properties.getUsername());
        message.setTo(email);
        message.setSubject("속닥속닥 인증코드입니다.");
        message.setText(authCode);

        javaMailSender.send(message);
    }
}

스프링의 설정 파일을 읽어서 MailProperties를 빈으로 만들어준다. 그래서 설정 값들을 편하게 가져올 수 있다.

Java MailSender 와의 비교

결국 내부적으로

java의 mailSender를 내부적으로 이용한다. 스프링은 그 외적으로 이것저것 더 처리를 해주는 것이다 (예외처리, 세션 맺기, 외부 설정 가져오기)

만약 Spring MailSender를 사용하지 않았더라면

@Configuration
@PropertySource("classpath:application.yml")
public class MailSenderConfig {

    @Value("${spring.mail.port}")
    private int port;

    @Value("${spring.mail.host}")
    private String host;

    @Value("${spring.mail.username}")
    private String username;

    @Value("${spring.mail.password}")
    private String password;

    @Value("${spring.mail.smtp.auth")
    private String auth;

    @Value("${spring.mail.smtp.starttls.enable")
    private String starttls;

    @Bean
    public JavaMailSender getJavaMailSender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        javaMailSender.setHost(host);
        javaMailSender.setPort(port);
        javaMailSender.setUsername(username);
        javaMailSender.setPassword(password);

        Properties properties = javaMailSender.getJavaMailProperties();
        properties.put("mail.smtp.starttls.enable", true);
        properties.put("mail.transport.protocol", "smtp");
        properties.put("mail.smtp.auth", auth);
        properties.put("mail.debug", "true");

        return javaMailSender;
    }
}

JavaMailSenderImpl에 관한 설정을 직접 가져와야 한다.

EmailSenderImpl

@Component
public class EmailSenderImpl implements EmailSender {

    public static final String FROM = "sokdakX2@gmail.com";

    private final JavaMailSender javaMailSender;

    public EmailSenderImpl(JavaMailSender javaMailSender) {
        this.javaMailSender = javaMailSender;
    }

    @Override
    public void send(String email, String authCode) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(FROM);
        message.setTo(email);
        message.setSubject("속닥속닥 인증코드입니다.");
        message.setText(authCode);

        javaMailSender.send(message);
    }
}

EmailSenderImpl도 빈으로 등록하고, 아까 빈으로 등록해두었던 JavaMailSender를 주입받을 수 있다.

또 위의 코드보다 사실 기타 설정 때문에 더 길어진다.

기타

  • 어떤 라이브러리를 쓸지는 깊이 비교 해보고 쓰는 습관을 들이자.
  • baeldung이라고 best practice만 있는 것이 아니다.

기타2

  • 외부 서비스를 사용함으로써 테스트 작성도 모킹을 이용하는 등 신경쓸 것들이 생겼다.
  • 이메일을 보내는 것이 시간이 많이 걸리므로 비동기나, 이벤트 등 다양한 방법으로 나중에 개선할 수도 있을 것 같다.

참고

제이슨

https://www.developer.com/design/working-with-javamail-and-the-spring-mail-apis/

https://www.baeldung.com/java-email

https://docs.spring.io/spring-framework/docs/1.1.x/reference/mail.html

1개의 댓글

comment-user-thumbnail
2022년 7월 14일

크.. 👍

답글 달기