Статьи

Фильтрация электронной почты с использованием Aspect и Spring Profile

Во время разработки веб-приложений часто возникает необходимость отправки электронных писем.

Однако иногда база данных заполняется производственными данными, и существует риск отправки электронных писем реальным клиентам во время выполнения теста электронной почты.

В этом посте объясняется, как этого избежать без явного написания кода в функции отправки электронной почты.

Мы бы использовали 2 метода:

  1. Spring Profiles — механизм, позволяющий указать, что представляет собой работающая среда (т.е. разработка, производство, ..)
  2. АОП — проще говоря, это механизм для написания дополнительной логики на методах в отрыве.

Я бы предположил, что у вас уже есть профили, установленные в ваших проектах, и сфокусируйтесь на аспектах.

В этом примере классом, который отправляет электронные письма, является EmailSender с методом send, как указано ниже:

01
02
03
04
05
06
07
08
09
10
public class EmailSender {
//empty default constructor is a must due to AOP limitation
public EmailSender() {}
 
//Sending email function
//EmailEntity - object which contains all data required for email sending (from, to, subject,..)
public void send(EmailEntity emailEntity) {
//logic to send email
}
}

Теперь мы добавим логику, которая предотвращает отправку электронной почты клиентам, когда код не запущен в производство.
Для этого мы будем использовать Аспекты, поэтому нам не придется записывать это в методе send, и тем самым мы будем поддерживать принцип разделения интересов.

Создайте класс, который будет содержать метод фильтрации:

1
2
3
4
5
6
@Aspect
@Component
public class EmailFilterAspect {
 
public EmailFilterAspect() {}
}

Затем создайте PointCut для отслеживания выполнения метода send:

1
2
@Pointcut("execution(public void com.mycompany.util.EmailSender.send(..))")
 public void sendEmail(){}

Поскольку нам нужно контролировать, должен ли метод выполняться или нет, нам нужно использовать аннотацию Arround.

1
2
3
4
5
6
7
8
@Around("sendEmail()")
public void emailFilterAdvice(ProceedingJoinPoint proceedingJoinPoint){
 try {
  proceedingJoinPoint.proceed(); //The send email method execution
 } catch (Throwable e) {                          
  e.printStackTrace();
 }
}

И наконец, нам нужно получить доступ к входному параметру метода отправки (т.е. получить EmailEntity) и убедиться, что мы не отправляем электронные письма клиентам в процессе разработки.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Around("sendEmail()")
 public void emailFilterAdvice(ProceedingJoinPoint proceedingJoinPoint){
 
 //Get current profile
ProfileEnum profile = ApplicationContextProvider.getActiveProfile();
 
Object[] args = proceedingJoinPoint.getArgs();        //get input parameters
        if (profile != ProfileEnum.PRODUCTION){
            //verify only internal mails are allowed
            for (Object object : args) {
                if (object instanceof EmailEntity){
                    String to = ((EmailEntity)object).getTo();
                    if (to!=null && to.endsWith("@mycompany.com")){//If not internal mail - Dont' continue the method                       
                        try {
                            proceedingJoinPoint.proceed();
                        } catch (Throwable e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }else{
            //In production don't restrict emails
            try {
                proceedingJoinPoint.proceed();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
}

Вот и все.
Что касается конфигурации, вам нужно включить аспектные jar в ваш проект.
В Maven это выглядит так:

01
02
03
04
05
06
07
08
09
10
11
org.aspectj
aspectjrt
${org.aspectj.version}
 
 
 
org.aspectj
aspectjweaver
${org.aspectj.version}
runtime

и в вашем весеннем конфигурационном XML-файле приложения вы должны иметь это:

1
 

Удачи!

Ссылка: фильтрация электронной почты с использованием Aspect и Spring Profile от нашего партнера по JCG Гал Левински в блоге Гал Левински .