[봄싹] 메일 서비스를 알림 서비스로 통합하기
알림 서비스는 현재 구글 토크와 트위터에 스터디와 모임 소식을 전달해주고 있습니다. 그런데 이전에 만든 메일 서비스가 이 것과 굉장히 비슷한 구조였습니다.
녹색은 스프링에서 제공하는 라이브러리이고, 파란색 계열이 봄싹 코드입니다. 보시면 알림 서비스와 거의 같은 구조지만, 사용하는 클래스가 조금 다르고, SendMailService가 구현하는 인터페이스가 없다는 것만 다를 뿐입니다.
이 두 개의 서비스를 사용하는 NotificationAspect를 보면 통합의 필요성을 더 확실하게 느낄 수 있습니다.
public class NotificationAspect {
@Autowired SendMailService sendMailService;
@Autowired JabberService messangerService;
@Autowired TwitterService twitterService;
@Autowired MemberService memberService;
...
@AfterReturning(pointcut = "addStudyPointcut() && args(study)", argNames="study")
public void sendMailAfterAddStudy(Study study){
sendMailService.sendMail(new StudyMail(study, StudyStatus.OPEN, memberService.getMemberList()));
StudyMessage msg = new StudyMessage(study, StudyStatus.OPEN, memberService.getMemberList());
messangerService.sendMessage(msg);
twitterService.sendMessage(msg);
}
...
@AfterReturning(pointcut = "addMeetingPointcut() && args(study, meeting)", argNames="study, meeting")
public void sendMailAfterAddMeeting(Study study, Meeting meeting){
sendMailService.sendMail(new MeetingMail(study, meeting, MeetingStatus.OPEN));
MeetingMessage msg = new MeetingMessage(study, meeting, MeetingStatus.OPEN);
messangerService.sendMessage(msg);
twitterService.sendMessage(msg);
}
}
sendMailService도 다른 알림 서비스와 같은 인터페이스를 구현하고, SpringSproutMessage 타입의 객체를 받아서 사용할 수 있다면. 어떤 일이 벌어질지 보이시나요?
저에게는 콜렉션이 보이고, 애스팩트의 여러 어브다이스에서 연달아 메서드를 호출해주는 구조의 중복을 제거할 수 있어 보입니다.
그래서 통합했습니다.
메시지쪽이 좀 까다로웠지만, 상속을 이용해서 나름 열심히 작업했습니다.
결과는 어떨까요?
1. 메시지 작성이 간편해졌습니다.
2. NotificationAspect가 다이어트를 했습니다.
원했던 성과를 거뒀습니다.
<value>sendMailService</value>
<value>jabberService</value>
<value>twitterService</value>
</util:list>
이렇게 빈 설정을 해 놓고..
public class NotificationAspect {
@Autowired List<NotificationService> notificationServices;
@Autowired MemberService memberService;
...
@AfterReturning(pointcut = "addStudyPointcut() && args(study)", argNames="study")
public void sendMailAfterAddStudy(Study study){
sendMsg(new StudyMailMessage(study, StudyStatus.OPEN, memberService.getMemberList()));
}
@AfterReturning(pointcut = "addMeetingPointcut() && args(study, meeting)", argNames="study, meeting")
public void sendMailAfterAddMeeting(Study study, Meeting meeting){
sendMsg(new MeetingMailMessage(study, meeting, MeetingStatus.OPEN));
}
private void sendMsg(SpringSproutMessage msg) {
for(NotificationService service : notificationServices)
service.sendMessage(msg);
}
...
}
NotificationAspect 코드를 이렇게 리팩토링 했습니다.
캬~~~ 엄청난 대규모 리팩토링이었는데 생각했던대로 되서 다행입니다. 이 작업을 진행하는 내내 테스트가 충분하지 않아서 굉장히 불안했었는데, 그래도 최소한의 테스트가 마지막 검증을 하는데 도움이 됐습니다. 역시.. 테스트는 있어야 합니다. 매우 필요한 존재에요;
다음 과제는 모임 등록시 SWF 적용하기!!