[Project] email ์ ์ก EventPublisher ํ์ฉ
Categories: Project
๐ ๊ฐ์ธ์ ์ธ ๊ณต๊ฐ์ผ๋ก ๊ณต๋ถ๋ฅผ ๊ธฐ๋กํ๊ณ ๋ณต์ตํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๋ธ๋ก๊ทธ์
๋๋ค.
์ ํํ์ง ์์ ์ ๋ณด๊ฐ ์์ ์ ์์ผ๋ ์ฐธ๊ณ ๋ฐ๋๋๋ค :๐ธ
[ํ๋ฆฐ ๋ด์ฉ์ ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์๋ฉด ๋ณต๋ฐ์ผ์ค๊ฑฐ์์]
EmailController์ ์ญํ ์ Event๋ก ์ฎ๊ธด ์ด์ ์ ๊ตฌํ ๊ณผ์
์ต๊ทผ ํ๋ก์ ํธ์์ ๊ธฐ์กด์ EmailController๊ฐ ๋ด๋นํ๋ ์ผ์ Event๋ก ์ฎ๊ธฐ๋ ๊ฒ ๋ ๋์ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ค์๋ค. ๊ทธ ์ด์ ๋, ๊ธฐ์กด ๋ก์ง์์๋ ํ์(member)์ ๋ฑ๋กํ๊ณ ๋์ ์ธ์ฆ ๋ฉ์ผ์ ๋ณด๋ด๊ณ , ์ฌ์ฉ์๊ฐ ์ธ์ฆ ์ฝ๋๋ฅผ ์ ๋ ฅํ๋ ๊ณผ์ ์์ ์ด ์ธ ๋ฒ์ ์์ฒญ์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ธฐ์กด ๋ก์ง์ ๋ฌธ์ ์
๋จผ์ , ๊ธฐ์กด ๋ก์ง์ ๊ฐ๋จํ ์ค๋ช ํ์๋ฉด ์ด๋ ๋ค:
- ์ฌ์ฉ์๊ฐ ํ์ ๊ฐ์ ์ ํ๋ฉด, ์์๋ก ๋ ๋์ค(Redis)์ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ,
- ๊ทธ ํ EmailController๋ฅผ ํตํด ์ธ์ฆ ๋ฉ์ผ์ ๋ฐ์กํ๊ณ ,
- ์ฌ์ฉ์๊ฐ ์ธ์ฆ ์ฝ๋๋ฅผ ์ ๋ ฅํ๋ฉด ๊ทธ์ ์ผ ํ์ ์ ๋ณด๋ฅผ DB์ ์ ์ฅํ๋ ๊ตฌ์กฐ๋ค.
์ด ๊ณผ์ ์์ Post ์์ฒญ์ ์ธ ๋ฒ์ด๋ ๋ณด๋ด์ผ ํ๋ค:
- ํ์ ๋ฑ๋ก ์
/members
๋ก ์์ฒญ - ์ด๋ฉ์ผ ์ ์ก ์
/send-mail
๋ก ์์ฒญ - ์ธ์ฆ ์ฝ๋ ์
๋ ฅ ์
/verify
๋ก ์์ฒญ
๋ฌผ๋ก ์ด ๊ตฌ์กฐ๋ ์ ์๋ํ๊ธด ํ์ง๋ง, ๋งค๋ฒ ์์ฒญ์ ๋ณด๋ด์ผ ํ๋ค ๋ณด๋ ๋ฒ๊ฑฐ๋กญ๊ณ , ์ฝ๋๋ ๋ณต์กํด์ก๋ค. ๊ทธ๋์ ์ด ๊ณผ์ ์ Event๋ก ์ฒ๋ฆฌํ๋ฉด ๋ ํจ์จ์ ์ด์ง ์์๊น ์๊ฐํ๊ฒ ๋๋ค.
Event๋ก ๋ก์ง์ ์ฎ๊ธด ์ด์
Event๋ก ๋ก์ง์ ์ฎ๊ธฐ๋ฉด, ํ์ ๋ฑ๋ก ์ ํ ๋ฒ์ ์์ฒญ์ผ๋ก ์ธ์ฆ ๋ฉ์ผ ๋ฐ์ก๊น์ง ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํด์ง๋ค. ์ด๋ก์จ ์์ฒญ ํ์๋ ์ค๊ณ , ์ฝ๋๋ ๊น๋ํด์ง๋ค.
๊ธฐ์กด์ EmailController์์ ์ฒ๋ฆฌํ๋ ๋ฉ์ผ ๋ฐ์ก ๋ก์ง์ Event๋ก ์ฎ๊ธฐ๋ฉด, ํ์(member)์ ๋ฑ๋กํ ๋ ์๋์ผ๋ก ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๊ณ , ๊ทธ ์ด๋ฒคํธ๋ฅผ ํตํด ๋ฉ์ผ์ด ์ ์ก๋๋ ๊ตฌ์กฐ๋ก ๋ณ๊ฒฝํ ์ ์๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํ์ ๋ฑ๋ก๊ณผ ๋์์ ์ด๋ฉ์ผ์ด ๋ฐ์ก๋๋ฏ๋ก ๋ณ๋์ ๋ฉ์ผ ๋ฐ์ก ์์ฒญ์ ํ ํ์๊ฐ ์๋ค.
Event ๊ตฌํ: ๊ฐ๋จํ๊ณ ํจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ
๋ณดํต Spring์์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ๋ ApplicationEvent
๋ฅผ ์์๋ฐ์ ์ฌ์ฉํ๊ณค ํ๋ค. ๊ทธ๋ฐ๋ฐ ์ต๊ทผ ์คํ๋ง ๋ฒ์ ์์๋ ๊ตณ์ด ApplicationEvent
๋ฅผ ์์๋ฐ์ง ์์๋ ๋๋ค๊ณ ํด์, ์ด๋ฒ์๋ ์์๋ฐ์ง ์๊ณ ๊ฐ๋จํ๊ฒ ๊ตฌํํด๋ดค๋ค.
๋ด๊ฐ ์ ํํ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค:
- ํ์ ๋ฑ๋ก ์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํค๊ณ ,
- ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ด ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ ์ด๋ฉ์ผ์ ๋ฐ์กํ๋ ๋ก์ง์ ์คํํ๋ค.
์ด ๊ณผ์ ์์ member
๊ฐ์ฒด์์ ํ์ํ email
์ ๋ณด๋ง ๊ฐ์ ธ์์ ๋ฉ์ผ์ ๋ณด๋ด๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ค. ์ด๋ ๊ฒ ๊ตฌํํ๋ฉด ๊ธฐ์กด์ ๋ก์ง๊ณผ ํฌ๊ฒ ๋ฌ๋ผ์ง์ง ์์ผ๋ฉด์๋, ์ด๋ฉ์ผ ๋ฐ์ก ๊ณผ์ ์ ๋ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
๊ตฌํ ๊ณผ์
- ์ด๋ฒคํธ ํด๋์ค ์์ฑ
-
์ด๋ฉ์ผ ๋ฐ์ก์ ์ํ ์ด๋ฒคํธ ํด๋์ค๋ฅผ ์์ฑํ๋ค. ์ด ํด๋์ค๋ ํ์ ๋ฑ๋ก ์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋ค.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
package com.springboot.helper.event; import com.springboot.member.entity.Member; import lombok.Getter; import org.springframework.context.ApplicationEvent; @Getter public class RegistrationEvent { private final Member member; public RegistrationEvent(Member member) { this.member = member; } }
-
- ์ด๋ฒคํธ ๋ฆฌ์ค๋
-
1 ์์ ๋ง๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฆฌ์ค๋(listener)๋ฅผ ๋ง๋ค์ด, ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋๋ง๋ค ์ด๋ฉ์ผ์ ๋ฐ์กํ๋๋ก ์ค์ ํ๋ค.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
package com.springboot.helper.event; import com.springboot.helper.email.EmailMessage; import com.springboot.helper.email.EmailService; import com.springboot.member.service.MemberService; import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.EventListener; import org.springframework.mail.MailSendException; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Component; @Component @EnableAsync @Slf4j public class MemberRegisterEventHandler { private final EmailService emailService; private final MemberService memberService; public MemberRegisterEventHandler(EmailService emailService, MemberService memberService) { this.emailService = emailService; this.memberService = memberService; } @EventListener public void listen(RegistrationEvent event) { try{ EmailMessage emailMessage = EmailMessage.builder() .to(event.getMember().getEmail()) .subject("[MeetBTI] ํ์๊ฐ์ ์ ์ํ ์ธ์ฆ์ฝ๋ ๋ฐ์ก") .build(); emailService.sendMail(emailMessage,"email"); } catch (MailSendException e) { log.error("MailSendException"); } catch (RuntimeException e) { log.error("RuntimeException : while sending"); } } }
-
์ด๋ฉ์ผ ์ปจํธ๋กค๋ฌ์์ ์ฌ์ฉ๋๋ ๊ฒ๋ค์ listen ๋ฉ์๋์ ์ ์ฉํ๋ค.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
package com.springboot.helper.email; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/send-mail") @RestController public class EmailController { private final EmailService emailService; public EmailController(EmailService emailService) { this.emailService = emailService; } //ํ์๊ฐ์ ์ด๋ฉ์ผ ์ธ์ฆ์ฝ๋ ๋ฐ์ก @PostMapping("/email") public ResponseEntity sendJoinMail(@RequestBody EmailPostDto emailPostDto) { EmailMessage emailMessage = EmailMessage.builder() .to(emailPostDto.getEmail()) .subject("[MeetBTI] ํ์๊ฐ์ ์ ์ํ ์ธ์ฆ์ฝ๋ ๋ฐ์ก") .build(); emailService.sendMail(emailMessage,"email"); String message = "์ธ์ฆ์ฝ๋๊ฐ ์ด๋ฉ์ผ๋ก ๋ฐ์ก๋์์ต๋๋ค."; return new ResponseEntity<>(message, HttpStatus.OK); } }
-
- ์ด๋ฒคํธ ๋ฐํ
-
ํ์ ๋ฑ๋ก์ด ์๋ฃ๋๋ฉด ์ด ์ด๋ฒคํธ๋ฅผ ๋ฐํ(publish)ํ๋๋ก ํ๋ค. ์ด๋ฅผ ํตํด ์ด๋ฉ์ผ ๋ฐ์ก ์์ฒญ์ด ์๋์ผ๋ก ์ด๋ฃจ์ด์ง๋ค.
1 2 3 4 5 6 7 8
public void createMember(Member member) { verifiedExistNickname(member.getNickname()); verifiedExistEmail(member.getEmail()); String key = member.getEmail() + ":email"; redisUtil.setHashValueWithExpire(key, "memberInfo", member, 600); publisher.publishEvent(new RegistrationEvent(member)); }
-
์ด๋ ๊ฒ ๋ก์ง์ Event๋ก ์ฎ๊ธฐ๊ณ ๋๋, ์ ์ฒด์ ์ธ ์ฝ๋๊ฐ ํจ์ฌ ๊น๋ํด์ก๋ค. ์ด์ ํ ๋ฒ์ ํ์ ๊ฐ์ ์์ฒญ์ผ๋ก ์ด๋ฉ์ผ ๋ฐ์ก๊น์ง ์๋์ผ๋ก ์ฒ๋ฆฌ๋๋, ์ฌ์ฉ์๋ ๋ ๊ฐํธํ๊ฒ ๊ฐ์ ํ ์ ์๊ณ ๋๋ ์์ฒญ์ด ์ค์ด์ ํธํด์ก๋ค!!!
ํ ์คํธ ๊ฒฐ๊ณผ ๋ฉ์ผ๋ ์ ์จ๋ค ๊ตฟ. (๊ทผ๋ฐ ๋ฉ์ผ ๋ฐ์ก์ด 5์ด๋ ๊ฑธ๋ฆฌ๋๊ฑด ์ด๋ป๊ฒ ํ์ง.)
Leave a comment