Однако иногда база данных заполняется производственными данными, и существует риск отправки электронных писем реальным клиентам во время выполнения теста электронной почты.
В этом посте объясняется, как этого избежать без явного написания кода в функции отправки электронной почты.
Мы бы использовали 2 метода:
- Spring Profiles — механизм, позволяющий указать, что представляет собой работающая среда (т.е. разработка, производство, ..)
- АОП — проще говоря, это механизм для написания дополнительной логики на методах в отрыве.
Я бы предположил, что у вас уже есть профили, установленные в ваших проектах, и сфокусируйтесь на аспектах.
В этом примере классом, который отправляет электронные письма, является EmailSender с методом send, как указано ниже:
|
01
02
03
04
05
06
07
08
09
10
|
public class EmailSender {//empty default constructor is a must due to AOP limitationpublic 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@Componentpublic 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 profileProfileEnum 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.aspectjaspectjrt${org.aspectj.version}org.aspectjaspectjweaver${org.aspectj.version}runtime |
и в вашем весеннем конфигурационном XML-файле приложения вы должны иметь это:
|
1
|
|
Удачи!
Ссылка: фильтрация электронной почты с использованием Aspect и Spring Profile от нашего партнера по JCG Гал Левински в блоге Гал Левински .