Однако иногда база данных заполняется производственными данными, и существует риск отправки электронных писем реальным клиентам во время выполнения теста электронной почты.
В этом посте объясняется, как этого избежать без явного написания кода в функции отправки электронной почты.
Мы бы использовали 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 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 Гал Левински в блоге Гал Левински .