В предыдущем посте я представил простой пример того, как добиться ориентации изображения весной с помощью ProxyFactoryBean и реализации интерфейса MethodBeforeAdvice.
На этом примере мы узнаем, как добиться ориентации сторон с помощью Spring boot и аннотаций Aspect4j.
Давайте начнем с нашего файла Gradle.
|
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
31
32
|
group 'com.gkatzioura'version '1.0-SNAPSHOT'apply plugin: 'java'apply plugin: 'idea'apply plugin: 'spring-boot'sourceCompatibility = 1.8buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE") }}repositories { mavenCentral()}dependencies { compile("org.springframework.boot:spring-boot-starter-web") { exclude module: "spring-boot-starter-tomcat" } compile("org.springframework.boot:spring-boot-starter-jetty") compile("org.slf4j:slf4j-api:1.6.6") compile("ch.qos.logback:logback-classic:1.0.13") compile("org.aspectj:aspectjweaver:1.8.8") testCompile("junit:junit:4.11")} |
Помимо весенних загрузочных плагинов мы должны включить пакет aspectjweaver.
Класс приложения
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
package com.gkatzioura.spring.aop;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ApplicationContext;/** * Created by gkatzioura on 5/28/16. */@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(); ApplicationContext applicationContext = springApplication.run(Application.class,args); }} |
Мы реализуем сервис, который будет выбирать образец для указанного имени.
Образец модели будет простым Pojo
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
package com.gkatzioura.spring.aop.model;/** * Created by gkatzioura on 5/28/16. */public class Sample { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }} |
Служба создаст образец объекта.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
package com.gkatzioura.spring.aop.service;import com.gkatzioura.spring.aop.model.Sample;import org.springframework.stereotype.Service;/** * Created by gkatzioura on 5/28/16. */@Servicepublic class SampleService { public Sample createSample(String sampleName) { Sample sample = new Sample(); sample.setName(sampleName); return sample; }} |
Все идет нормально. Предположим, что мы хотим выполнить некоторые действия до и после создания образца. АОП весной может помочь нам сделать это.
Функция createSample является JoinPoint. Основная концепция — работа с советами. Из документации рекомендуется действие, предпринимаемое аспектом в определенной точке соединения.
В нашем случае мы хотим сделать некоторые дополнительные записи перед созданием образца. Поэтому мы будем использовать тип «До консультации».
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package com.gkatzioura.spring.aop.aspect;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;/** * Created by gkatzioura on 5/28/16. */@Aspect@Componentpublic class SampleServiceAspect { private static final Logger LOGGER = LoggerFactory.getLogger(SampleServiceAspect.class); @Before("execution(* com.gkatzioura.spring.aop.service.SampleService.createSample (java.lang.String)) && args(sampleName)") public void beforeSampleCreation(String sampleName) { LOGGER.info("A request was issued for a sample name: "+sampleName); }} |
Мы реализовали функцию с аннотацией @Before. Аргумент, который мы предоставляем аннотации, является выражением pointcut. Выражения pointcut помогают нам в определении функции, которая будет запускать наш совет и аргументы функции, которые следует использовать. Поэтому, прежде чем метод createSample будет запущен, на нашем экране должно появиться сообщение журнала.
Предположим, что мы хотим иметь больше действий до и после выполнения метода или даже изменить результат функции createSample, мы можем использовать @Around Advice.
|
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
31
32
33
34
35
36
37
38
39
40
|
package com.gkatzioura.spring.aop.aspect;import com.gkatzioura.spring.aop.model.Sample;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;/** * Created by gkatzioura on 5/28/16. */@Aspect@Componentpublic class SampleServiceAspect { private static final Logger LOGGER = LoggerFactory.getLogger(SampleServiceAspect.class); @Before("execution(* com.gkatzioura.spring.aop.service.SampleService.createSample (java.lang.String)) && args(sampleName)") public void beforeSampleCreation(String sampleName) { LOGGER.info("A request was issued for a sample name: "+sampleName); } @Around("execution(* com.gkatzioura.spring.aop.service.SampleService.createSample (java.lang.String)) && args(sampleName)") public Object aroundSampleCreation(ProceedingJoinPoint proceedingJoinPoint,String sampleName) throws Throwable { LOGGER.info("A request was issued for a sample name: "+sampleName); sampleName = sampleName+"!"; Sample sample = (Sample) proceedingJoinPoint.proceed(new Object[] {sampleName}); sample.setName(sample.getName().toUpperCase()); return sample; }} |
Как мы видим, совет директоров aroundSampleCreation меняет входные данные, а также меняет результат. Вы можете найти исходный код на GitHub
| Ссылка: | Аспектно-ориентированное программирование с помощью Spring Boot от нашего партнера JCG Эммануила Гкатциоураса в блоге gkatzioura . |