스프링과 JPA 기반 웹 애플리케이션 개발 #51 EmailService 추상화

스프링과 JPA 기반 웹 애플리케이션 개발 #51 EmailService 추상화

해당 내용은 인프런, 스프링과 JPA 기반 웹 애플리케이션 개발의 강의 내용을 바탕으로 작성된 내용입니다.

강의를 학습하며 요약한 내용을 출처를 표기하고 블로깅 또는 문서로 공개하는 것을 허용합니다 라는 원칙 하에 요약 내용을 공개합니다. 출처는 위에 언급되어있듯, 인프런, 스프링과 JPA 기반 웹 애플리케이션 개발입니다.

제가 학습한 소스코드는 https://github.com/n00nietzsche/jakestudy_webapp 에 지속적으로 업로드 됩니다. 매 커밋 메세지에 강의의 어디 부분까지 진행됐는지 기록해놓겠습니다.


MimeMessage 전송하기

  • HTML 이메일 전송하기
    • MimeMessage 전송
    • MimeMessageHelper: MimeMessage 만들 때 사용할 수 있는 유틸리티
  • EmailService 인터페이스
    • void sendEmail(EmailMessage emailMessage);
  • EmailService 인터페이스 구현체
    • ConsoleEmailService: 콘솔 출력
    • HtmlEmailService: JavaMailSender를 사용해서 HTML로 메일 전송

EmailService 추상화의 목적

기존 JavaMailSender 객체는 MimeMessageSimpleMailMessage를 받아서 상황(profile)에 따라 콘솔에서만 출력하거나 실제 메일을 보내거나 하는 기능을 하는 메소드가 없다.

그래서 MimeMessageSimpleMailMessage에서 우리가 이용하는 공통 속성들인 문자열 to, subject, text만 빼서 EmailMessage라는 것으로 추상화하고, EmailService라는 클래스를 만들어 profilelocal인지 dev인지 확인 후에 실제로 메일을 보내거나 혹은 콘솔에만 출력하는 메소드를 만들 것이다.

EmailMessage 클래스 정의

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class EmailMessage {
    private String to;
    private String subject;
    private String text;
}

EmailService 클래스 정의

public interface EmailService {
    void sendEmail(EmailMessage emailMessage);
}

ConsoleEmailService 클래스 정의

@Slf4j
@Profile("local")
@Component
public class ConsoleEmailService implements EmailService{
    @Override
    public void sendEmail(EmailMessage emailMessage) {
        log.info("sent email: {}", emailMessage.getText());
    }
}

EmailService를 상속한 클래스이다. profilelocal이면 위의 클래스의 빈이 스프링 컨테이너에 올라간다. 실제로 메일을 보내진 않고 출력만 도와준다.

HtmlEmailService 클래스 정의

@Slf4j
@Profile("dev")
@Component
@RequiredArgsConstructor
public class HtmlEmailService implements EmailService{

    private final JavaMailSender javaMailSender;

    @Override
    public void sendEmail(EmailMessage emailMessage) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "UTF-8");
            mimeMessageHelper.setTo(emailMessage.getTo());
            mimeMessageHelper.setSubject(emailMessage.getSubject());
            mimeMessageHelper.setText(emailMessage.getText(), false);
            javaMailSender.send(mimeMessage);
            log.info("sent email: {}", emailMessage.getText());
        } catch (MessagingException e) {
            e.printStackTrace();
            log.error("failed to send email", e);
        }

    }
}

동일하게 EmailService를 상속한 클래스이다. profiledev인 경우에 위의 클래스가 스프링 컨테이너에 빈으로 올라간다. ConsoleEmailServiceHtmlEmailService는 다형성을 통해 상위 타입(EmailService)의 빈의 같은 멤버에 주입될 수 있다.

그래서 AccountService의 내용을 다음과 같이 만들면, ConsoleEmailserviceHtmlEmailServiceprofile에 따라 코드는 변경하지 않고 이용할 수 있다.

...
        EmailMessage emailMessage = new EmailMessage(
                account.getEmail(),
                "회원가입 인증",
                "/check-email-token?token=" + account.getEmailCheckToken() + "&email=" + account.getEmail()
        );

        emailService.sendEmail(emailMessage);
...

좋은 웹페이지 즐겨찾기