서버를 만들다 보면 메일을 인증하거나, 안내 메일을 전송하는 로직이 필요한 경우가 종종 있습니다.
자바에서 메일을 발송할 때는 JavaMail을 사용하면 됩니다. javax.mail 패키지에서 제공하는 자바의 이메일 클래스를 사용하면 다음과 같은 메일 발송 메소드를 만들 수 있습니다.
private void sendUpgradeEMail(User user) {
Properites props = new Properties();
props.put("mail.smtp.host", "mail.ksug.org");
Session s = Session.getInstance(props, null);
MimeMessage message = new MimeMessage(s);
try {
message.setFrom(new InternetAddress("useradmin@ksug.org"));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail()));
message.setSubject("제목을 입력합니다");
message.setText("내용을 입력합니다");
Transport.send(message);
} catch(AddressException e) {
throw new RuntimeException(e);
} catch(MessagingException e) {
thorw new RuntimeException(e);
} catch(UnsupportedEncodingException e) {
thorw new RuntimeException(e)
}
}
이렇게 잘만든 메소드를 테스트하기 위해선 사용자의 정보를 업데이트시 발송되는 메일을 확인해야 합니다. 하지만 메일 전송 상당히 과부하가 많이 발생하는 작업이기에 매번 테스트시 메일을 발송하는 것은 바람직해 보이지 않습니다. 그렇다면 테스트용 JavaMail로 대체하는 것이 필요해 보입니다.
서비스 추상화
package org.springframework.mail;
...
public interface MailSender {
void send(SimpleMailMessage simpleMessage) throws MailException;
void send(SimpleMailMessage[] simpleMessage) throws MailException;
}
위와 같은 인터페이스를 스프링에서 제공해줍니다. 이 인터페이스는 SimpleMailMessage라는 인터페이스를 구현한 클래스에 담긴 메일 메시지를 전송하는 메소드로 이루어져 있습니다. 이를 사용하면
private void sendUpgradeEMail(User user) {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("mail.server.com");
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setTo(user.getEmail());
mailMessage.setFrom("useradmin@ksug.org");
mailMessage.setSubject("제목입력");
mailMessage.setText("내용 입력");
mailSender.send(mailMessage);
}
와 같이 try/catch 블록이 사라진 것을 볼 수 있습니다. 스프링의 예외처리 원칙에 따라서 JavaMail을 처리하는 중에 발생한 각종 예외를 MailException이라는 런타임 예외로 포장해서 던져주기 때문에 귀찮은 try/catch 블록을 만들지 않아도 됩니다. 이제 DI를 적용하기 위해 JavaMailSenderImpl mailSender = new JavaMailSenderImpl()와 mailSender.setHost("mail.server.com")를 없애고 UserService 클래스에 MailSender(mailSender) 인터페이스 타입의 변수를 만들고 @Autowired를 통해 주입해주면 됩니다.
보통 서비스 추상화란 트랜잭션과 같이 기능은 유사하나 사용 방법이 다른 로우레벨의 다양한 기술에 대한 추상 인터페이스와 일관성 있는 접근 방법을 제공해주는 것을 말합니다.
'Spring' 카테고리의 다른 글
IoC 컨테이너란 무엇인가 (0) | 2024.04.16 |
---|---|
어노테이션이란? (0) | 2024.04.02 |
트랜잭션 어노테이션 (@Transactional, 속성, 정책, 방법) (0) | 2024.03.28 |
Mockito 프레임워크 정리(TDD 작성, 테스트 코드 작성) (0) | 2024.03.22 |
트랜잭션 (1) | 2024.03.16 |