From 5ce7d19c6adaa03878b643b0f15bfb10eed3636c Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Tue, 16 Dec 2025 19:23:59 +0300 Subject: [PATCH] 2025-11 spring-04-aop --- .../spring-04-aop/aop-classwork/.gitignore | 24 ++++ .../aop-classwork/exercise/pom.xml | 42 +++++++ .../src/main/java/ru/otus/spring/Main.java | 23 ++++ .../java/ru/otus/spring/dao/PersonDao.java | 8 ++ .../ru/otus/spring/dao/PersonDaoSimple.java | 14 +++ .../java/ru/otus/spring/domain/Person.java | 5 + .../ru/otus/spring/logging/LoggingAspect.java | 14 +++ .../ru/otus/spring/service/PersonService.java | 8 ++ .../spring/service/PersonServiceImpl.java | 21 ++++ 2025-11/spring-04-aop/aop-classwork/pom.xml | 17 +++ .../aop-classwork/solution/pom.xml | 44 ++++++++ .../src/main/java/ru/otus/spring/Main.java | 25 +++++ .../java/ru/otus/spring/dao/PersonDao.java | 8 ++ .../ru/otus/spring/dao/PersonDaoSimple.java | 16 +++ .../java/ru/otus/spring/domain/Person.java | 5 + .../java/ru/otus/spring/logging/LogMe.java | 11 ++ .../otus/spring/logging/Logging2Aspect.java | 21 ++++ .../ru/otus/spring/logging/LoggingAspect.java | 19 ++++ .../ru/otus/spring/service/PersonService.java | 8 ++ .../spring/service/PersonServiceImpl.java | 21 ++++ 2025-11/spring-04-aop/aop-demo/.gitignore | 24 ++++ .../aop-demo/aop-ctw-plain/exec.sh | 3 + .../aop-demo/aop-ctw-plain/pom.xml | 93 ++++++++++++++++ .../src/main/java/ru/otus/spring/Main.java | 25 +++++ .../java/ru/otus/spring/dao/PersonDao.java | 8 ++ .../ru/otus/spring/dao/PersonDaoSimple.java | 11 ++ .../java/ru/otus/spring/domain/Person.java | 5 + .../ru/otus/spring/logging/LoggingAspect.java | 17 +++ .../ru/otus/spring/service/PersonService.java | 8 ++ .../spring/service/PersonServiceImpl.java | 18 +++ .../spring-04-aop/aop-demo/aop-ctw/exec.sh | 3 + .../spring-04-aop/aop-demo/aop-ctw/pom.xml | 104 ++++++++++++++++++ .../src/main/java/ru/otus/spring/Main.java | 29 +++++ .../java/ru/otus/spring/dao/PersonDao.java | 8 ++ .../ru/otus/spring/dao/PersonDaoSimple.java | 13 +++ .../java/ru/otus/spring/domain/Person.java | 20 ++++ .../ru/otus/spring/logging/LoggingAspect.java | 17 +++ .../ru/otus/spring/service/PersonService.java | 8 ++ .../spring/service/PersonServiceImpl.java | 20 ++++ .../spring-04-aop/aop-demo/aop-custom/pom.xml | 38 +++++++ .../src/main/java/ru/otus/demo/Main.java | 69 ++++++++++++ .../main/java/ru/otus/demo/MainSimple.java | 67 +++++++++++ .../java/ru/otus/demo/aop/LoggingAspect.java | 20 ++++ .../demo/aop/SimpleAOPInvocationHandler.java | 24 ++++ .../ru/otus/demo/aop/SimpleJoinPoint.java | 67 +++++++++++ .../ru/otus/demo/aop/SimpleSignature.java | 43 ++++++++ .../java/ru/otus/demo/aop/SimpleWeaver.java | 16 +++ .../main/java/ru/otus/demo/dao/BookDao.java | 8 ++ .../java/ru/otus/demo/dao/BookDaoSimple.java | 10 ++ .../main/java/ru/otus/demo/dao/PersonDao.java | 8 ++ .../ru/otus/demo/dao/PersonDaoSimple.java | 12 ++ .../main/java/ru/otus/demo/domain/Book.java | 5 + .../main/java/ru/otus/demo/domain/Person.java | 12 ++ .../ru/otus/demo/service/BookService.java | 8 ++ .../ru/otus/demo/service/BookServiceImpl.java | 17 +++ .../ru/otus/demo/service/PersonService.java | 8 ++ .../otus/demo/service/PersonServiceImpl.java | 18 +++ .../spring-04-aop/aop-demo/aop-ltw/exec.sh | 3 + .../spring-04-aop/aop-demo/aop-ltw/pom.xml | 80 ++++++++++++++ .../src/main/java/ru/otus/spring/Main.java | 31 ++++++ .../java/ru/otus/spring/dao/PersonDao.java | 8 ++ .../ru/otus/spring/dao/PersonDaoSimple.java | 16 +++ .../java/ru/otus/spring/domain/Person.java | 5 + .../ru/otus/spring/logging/LoggingAspect.java | 17 +++ .../ru/otus/spring/service/PersonService.java | 8 ++ .../spring/service/PersonServiceImpl.java | 20 ++++ .../src/main/resources/META-INF/aop.xml | 13 +++ .../spring-04-aop/aop-demo/aop-native/pom.xml | 42 +++++++ .../src/main/java/ru/otus/spring/Main.java | 22 ++++ .../spring/config/CommonNativeAopConfig.java | 17 +++ .../spring/config/LoggingAspectConfig.java | 39 +++++++ .../java/ru/otus/spring/dao/PersonDao.java | 8 ++ .../ru/otus/spring/dao/PersonDaoSimple.java | 13 +++ .../java/ru/otus/spring/domain/Person.java | 5 + .../ru/otus/spring/service/PersonService.java | 8 ++ .../spring/service/PersonServiceImpl.java | 20 ++++ 2025-11/spring-04-aop/aop-demo/pom.xml | 20 ++++ 77 files changed, 1633 insertions(+) create mode 100644 2025-11/spring-04-aop/aop-classwork/.gitignore create mode 100644 2025-11/spring-04-aop/aop-classwork/exercise/pom.xml create mode 100644 2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/Main.java create mode 100644 2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/dao/PersonDao.java create mode 100644 2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java create mode 100644 2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/logging/LoggingAspect.java create mode 100644 2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/service/PersonService.java create mode 100644 2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/service/PersonServiceImpl.java create mode 100644 2025-11/spring-04-aop/aop-classwork/pom.xml create mode 100644 2025-11/spring-04-aop/aop-classwork/solution/pom.xml create mode 100644 2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/Main.java create mode 100644 2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/dao/PersonDao.java create mode 100644 2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java create mode 100644 2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/LogMe.java create mode 100644 2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/Logging2Aspect.java create mode 100644 2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/LoggingAspect.java create mode 100644 2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/service/PersonService.java create mode 100644 2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/service/PersonServiceImpl.java create mode 100644 2025-11/spring-04-aop/aop-demo/.gitignore create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw-plain/exec.sh create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw-plain/pom.xml create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/Main.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/dao/PersonDao.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/logging/LoggingAspect.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/service/PersonService.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/service/PersonServiceImpl.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw/exec.sh create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw/pom.xml create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/Main.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/dao/PersonDao.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/logging/LoggingAspect.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/service/PersonService.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/service/PersonServiceImpl.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/pom.xml create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/Main.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/MainSimple.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/LoggingAspect.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleAOPInvocationHandler.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleJoinPoint.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleSignature.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleWeaver.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/BookDao.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/BookDaoSimple.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/PersonDao.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/PersonDaoSimple.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/domain/Book.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/domain/Person.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/BookService.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/BookServiceImpl.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/PersonService.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/PersonServiceImpl.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ltw/exec.sh create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ltw/pom.xml create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/Main.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/dao/PersonDao.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/logging/LoggingAspect.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/service/PersonService.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/service/PersonServiceImpl.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/resources/META-INF/aop.xml create mode 100644 2025-11/spring-04-aop/aop-demo/aop-native/pom.xml create mode 100644 2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/Main.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/config/CommonNativeAopConfig.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/config/LoggingAspectConfig.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/dao/PersonDao.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/service/PersonService.java create mode 100644 2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/service/PersonServiceImpl.java create mode 100644 2025-11/spring-04-aop/aop-demo/pom.xml diff --git a/2025-11/spring-04-aop/aop-classwork/.gitignore b/2025-11/spring-04-aop/aop-classwork/.gitignore new file mode 100644 index 00000000..4ea52072 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/.gitignore @@ -0,0 +1,24 @@ +target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ diff --git a/2025-11/spring-04-aop/aop-classwork/exercise/pom.xml b/2025-11/spring-04-aop/aop-classwork/exercise/pom.xml new file mode 100644 index 00000000..b2149392 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/exercise/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + ru.otus + exercise + 1.0 + + + 17 + 17 + 6.0.9 + + 1.9.19 + + + + + org.springframework + spring-context + ${spring.version} + + + + org.springframework + spring-aop + ${spring.version} + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + diff --git a/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/Main.java b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..e500c9d5 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,23 @@ +package ru.otus.spring; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import ru.otus.spring.domain.Person; +import ru.otus.spring.service.PersonService; + +@Configuration +@ComponentScan +public class Main { + + public static void main(String[] args) { + AnnotationConfigApplicationContext context = + new AnnotationConfigApplicationContext(Main.class); + + PersonService service = context.getBean(PersonService.class); + + Person ivan = service.getByName("Ivan"); + System.out.println("name: " + ivan.name() + " age: " + ivan.age()); + } +} diff --git a/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/dao/PersonDao.java b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/dao/PersonDao.java new file mode 100644 index 00000000..d33939bd --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/dao/PersonDao.java @@ -0,0 +1,8 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public interface PersonDao { + + Person findByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java new file mode 100644 index 00000000..bb3d44f7 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java @@ -0,0 +1,14 @@ +package ru.otus.spring.dao; + +import org.springframework.stereotype.Repository; + +import ru.otus.spring.domain.Person; + +@Repository +public class PersonDaoSimple implements PersonDao { + + @Override + public Person findByName(String name) { + return new Person(name, 18); + } +} diff --git a/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/domain/Person.java b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..9ba649d1 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,5 @@ +package ru.otus.spring.domain; + +public record Person(String name, int age) { + +} diff --git a/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/logging/LoggingAspect.java b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/logging/LoggingAspect.java new file mode 100644 index 00000000..e066196d --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/logging/LoggingAspect.java @@ -0,0 +1,14 @@ +package ru.otus.spring.logging; + +import org.aspectj.lang.JoinPoint; + + +public class LoggingAspect { + + public void logBefore(JoinPoint joinPoint) { + System.out.println("Прокси : " + joinPoint.getThis().getClass().getName()); + System.out.println("Класс : " + joinPoint.getTarget().getClass().getName()); + + System.out.println("Вызов метода : " + joinPoint.getSignature().getName()); + } +} diff --git a/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/service/PersonService.java b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/service/PersonService.java new file mode 100644 index 00000000..9b83e7de --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/service/PersonService.java @@ -0,0 +1,8 @@ +package ru.otus.spring.service; + +import ru.otus.spring.domain.Person; + +public interface PersonService { + + Person getByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/service/PersonServiceImpl.java b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/service/PersonServiceImpl.java new file mode 100644 index 00000000..dd0d1e23 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/exercise/src/main/java/ru/otus/spring/service/PersonServiceImpl.java @@ -0,0 +1,21 @@ +package ru.otus.spring.service; + +import org.springframework.stereotype.Service; + +import ru.otus.spring.dao.PersonDao; +import ru.otus.spring.domain.Person; + +@Service +public class PersonServiceImpl implements PersonService { + + private final PersonDao dao; + + public PersonServiceImpl(PersonDao dao) { + this.dao = dao; + } + + @Override + public Person getByName(String name) { + return dao.findByName(name); + } +} diff --git a/2025-11/spring-04-aop/aop-classwork/pom.xml b/2025-11/spring-04-aop/aop-classwork/pom.xml new file mode 100644 index 00000000..2f9b1745 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + ru.otus + aop-classwork + 1.0 + + pom + + + exercise + solution + + diff --git a/2025-11/spring-04-aop/aop-classwork/solution/pom.xml b/2025-11/spring-04-aop/aop-classwork/solution/pom.xml new file mode 100644 index 00000000..02f4bb95 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/solution/pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + + ru.otus + solution + 1.0 + + + 17 + 17 + 6.0.9 + + 1.9.19 + + UTF-8 + + + + + org.springframework + spring-context + ${spring.version} + + + + org.springframework + spring-aop + ${spring.version} + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + diff --git a/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/Main.java b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..ef271c9f --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,25 @@ +package ru.otus.spring; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +import ru.otus.spring.domain.Person; +import ru.otus.spring.service.PersonService; + +@EnableAspectJAutoProxy +@Configuration +@ComponentScan +public class Main { + + public static void main(String[] args) { + AnnotationConfigApplicationContext context = + new AnnotationConfigApplicationContext(Main.class); + + PersonService service = context.getBean(PersonService.class); + + Person ivan = service.getByName("Ivan"); + System.out.println("name: " + ivan.name() + " age: " + ivan.age()); + } +} diff --git a/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/dao/PersonDao.java b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/dao/PersonDao.java new file mode 100644 index 00000000..d33939bd --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/dao/PersonDao.java @@ -0,0 +1,8 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public interface PersonDao { + + Person findByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java new file mode 100644 index 00000000..b9973d1a --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java @@ -0,0 +1,16 @@ +package ru.otus.spring.dao; + +import org.springframework.stereotype.Repository; + +import ru.otus.spring.domain.Person; +import ru.otus.spring.logging.LogMe; + +@Repository +public class PersonDaoSimple implements PersonDao { + + @Override + @LogMe + public Person findByName(String name) { + return new Person(name, 18); + } +} diff --git a/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/domain/Person.java b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..9ba649d1 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,5 @@ +package ru.otus.spring.domain; + +public record Person(String name, int age) { + +} diff --git a/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/LogMe.java b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/LogMe.java new file mode 100644 index 00000000..cc2ef8c4 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/LogMe.java @@ -0,0 +1,11 @@ +package ru.otus.spring.logging; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface LogMe { +} diff --git a/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/Logging2Aspect.java b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/Logging2Aspect.java new file mode 100644 index 00000000..ecf4a6f2 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/Logging2Aspect.java @@ -0,0 +1,21 @@ +package ru.otus.spring.logging; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +@Aspect +@Order(1) +@Component +public class Logging2Aspect { + + @Before("@annotation(ru.otus.spring.logging.LogMe)") + public void logBefore(JoinPoint joinPoint) { + System.out.println("Прокси2 : " + joinPoint.getThis().getClass().getName()); + System.out.println("Класс2 : " + joinPoint.getTarget().getClass().getName()); + + System.out.println("Вызов метода2 : " + joinPoint.getSignature().getName()); + } +} diff --git a/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/LoggingAspect.java b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/LoggingAspect.java new file mode 100644 index 00000000..4da7fce8 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/logging/LoggingAspect.java @@ -0,0 +1,19 @@ +package ru.otus.spring.logging; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.springframework.stereotype.Component; + +@Aspect +@Component +public class LoggingAspect { + + @Before("@annotation(ru.otus.spring.logging.LogMe)") + public void logBefore(JoinPoint joinPoint) { + System.out.println("Прокси : " + joinPoint.getThis().getClass().getName()); + System.out.println("Класс : " + joinPoint.getTarget().getClass().getName()); + + System.out.println("Вызов метода : " + joinPoint.getSignature().getName()); + } +} diff --git a/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/service/PersonService.java b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/service/PersonService.java new file mode 100644 index 00000000..9b83e7de --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/service/PersonService.java @@ -0,0 +1,8 @@ +package ru.otus.spring.service; + +import ru.otus.spring.domain.Person; + +public interface PersonService { + + Person getByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/service/PersonServiceImpl.java b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/service/PersonServiceImpl.java new file mode 100644 index 00000000..dd0d1e23 --- /dev/null +++ b/2025-11/spring-04-aop/aop-classwork/solution/src/main/java/ru/otus/spring/service/PersonServiceImpl.java @@ -0,0 +1,21 @@ +package ru.otus.spring.service; + +import org.springframework.stereotype.Service; + +import ru.otus.spring.dao.PersonDao; +import ru.otus.spring.domain.Person; + +@Service +public class PersonServiceImpl implements PersonService { + + private final PersonDao dao; + + public PersonServiceImpl(PersonDao dao) { + this.dao = dao; + } + + @Override + public Person getByName(String name) { + return dao.findByName(name); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/.gitignore b/2025-11/spring-04-aop/aop-demo/.gitignore new file mode 100644 index 00000000..4ea52072 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/.gitignore @@ -0,0 +1,24 @@ +target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/exec.sh b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/exec.sh new file mode 100644 index 00000000..4af59274 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/exec.sh @@ -0,0 +1,3 @@ +mvn clean package +java -jar target/aop-ctw-plain-1.0-jar-with-dependencies.jar +read -p "Press enter to continue" \ No newline at end of file diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/pom.xml b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/pom.xml new file mode 100644 index 00000000..b28feca4 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + + ru.otus + aop-ctw-plain + 1.0 + + + UTF-8 + 17 + 17 + 1.9.19 + 1.13.1 + + + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + + dev.aspectj + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + jar-with-dependencies + + + + ru.otus.spring.Main + + + + + + make-assembly + package + + single + + + + + + dev.aspectj + aspectj-maven-plugin + ${aspectj.plugin.version} + + 17 + ${maven.compiler.source} + ${maven.compiler.target} + true + true + ignore + UTF-8 + + ${project.build.directory}/classes + + true + + + + + compile + + + + + + + + + diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/Main.java b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..5df2177f --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,25 @@ +package ru.otus.spring; + +import ru.otus.spring.dao.PersonDao; +import ru.otus.spring.dao.PersonDaoSimple; +import ru.otus.spring.domain.Person; +import ru.otus.spring.service.PersonService; +import ru.otus.spring.service.PersonServiceImpl; + +/* +Запуск примера: + 1. cd aop-demo/aop-ctw-plain/ + 2. mvn clean package + 3. java -jar target/aop-ctw-plain-1.0-jar-with-dependencies.jar + */ + +public class Main { + + public static void main(String[] args) { + PersonDao personDao = new PersonDaoSimple(); + PersonService service = new PersonServiceImpl(personDao); + + Person ivan = service.getByName("Ivan"); + System.out.println("name: " + ivan.name() + " age: " + ivan.age()); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/dao/PersonDao.java b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/dao/PersonDao.java new file mode 100644 index 00000000..d33939bd --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/dao/PersonDao.java @@ -0,0 +1,8 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public interface PersonDao { + + Person findByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java new file mode 100644 index 00000000..8f98abd0 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java @@ -0,0 +1,11 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public class PersonDaoSimple implements PersonDao { + + @Override + public Person findByName(String name) { + return new Person(name, 18); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/domain/Person.java b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..9ba649d1 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,5 @@ +package ru.otus.spring.domain; + +public record Person(String name, int age) { + +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/logging/LoggingAspect.java b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/logging/LoggingAspect.java new file mode 100644 index 00000000..e77adb73 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/logging/LoggingAspect.java @@ -0,0 +1,17 @@ +package ru.otus.spring.logging; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; + +@Aspect +public class LoggingAspect { + + @Before("execution(* ru.otus.spring.dao.PersonDaoSimple.*(..))") + public void logBefore(JoinPoint joinPoint) { + System.out.println("Прокси : " + joinPoint.getThis().getClass().getName()); + System.out.println("Класс : " + joinPoint.getTarget().getClass().getName()); + + System.out.println("Вызов метода : " + joinPoint.getSignature().getName()); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/service/PersonService.java b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/service/PersonService.java new file mode 100644 index 00000000..9b83e7de --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/service/PersonService.java @@ -0,0 +1,8 @@ +package ru.otus.spring.service; + +import ru.otus.spring.domain.Person; + +public interface PersonService { + + Person getByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/service/PersonServiceImpl.java b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/service/PersonServiceImpl.java new file mode 100644 index 00000000..d4968d49 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw-plain/src/main/java/ru/otus/spring/service/PersonServiceImpl.java @@ -0,0 +1,18 @@ +package ru.otus.spring.service; + +import ru.otus.spring.dao.PersonDao; +import ru.otus.spring.domain.Person; + +public class PersonServiceImpl implements PersonService { + + private final PersonDao dao; + + public PersonServiceImpl(PersonDao dao) { + this.dao = dao; + } + + @Override + public Person getByName(String name) { + return dao.findByName(name); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw/exec.sh b/2025-11/spring-04-aop/aop-demo/aop-ctw/exec.sh new file mode 100644 index 00000000..347ebc16 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw/exec.sh @@ -0,0 +1,3 @@ +mvn clean package +java -jar target/aop-ctw-1.0-jar-with-dependencies.jar +read -p "Press enter to continue" \ No newline at end of file diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw/pom.xml b/2025-11/spring-04-aop/aop-demo/aop-ctw/pom.xml new file mode 100644 index 00000000..ceecf353 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + + ru.otus + aop-ctw + 1.0 + + + UTF-8 + 11 + 11 + 6.0.9 + 1.9.19 + 1.13.1 + + + + + org.springframework + spring-context + ${spring.version} + + + + org.springframework + spring-aop + ${spring.version} + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + + dev.aspectj + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + jar-with-dependencies + + + + ru.otus.spring.Main + + + + + + make-assembly + package + + single + + + + + + dev.aspectj + aspectj-maven-plugin + ${aspectj.plugin.version} + + 17 + ${maven.compiler.source} + ${maven.compiler.target} + true + true + ignore + UTF-8 + + ${project.build.directory}/classes + + true + + + + + compile + + + + + + + + + diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/Main.java b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..8a9075fc --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,29 @@ +package ru.otus.spring; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import ru.otus.spring.domain.Person; +import ru.otus.spring.service.PersonService; + +/* +Запуск примера: + 1. cd aop-demo/aop-ctw/ + 2. mvn clean package + 3. java -jar target/aop-ctw-1.0-jar-with-dependencies.jar + */ + +@Configuration +@ComponentScan +public class Main { + + public static void main(String[] args) { + AnnotationConfigApplicationContext context = + new AnnotationConfigApplicationContext(Main.class); + + PersonService service = context.getBean(PersonService.class); + + Person ivan = service.getByName("Ivan"); + System.out.println("name: " + ivan.getName() + " age: " + ivan.getAge()); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/dao/PersonDao.java b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/dao/PersonDao.java new file mode 100644 index 00000000..d33939bd --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/dao/PersonDao.java @@ -0,0 +1,8 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public interface PersonDao { + + Person findByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java new file mode 100644 index 00000000..b39e82b5 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java @@ -0,0 +1,13 @@ +package ru.otus.spring.dao; + +import org.springframework.stereotype.Repository; +import ru.otus.spring.domain.Person; + +@Repository +public class PersonDaoSimple implements PersonDao { + + @Override + public Person findByName(String name) { + return new Person(name, 18); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/domain/Person.java b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..c23be0c6 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,20 @@ +package ru.otus.spring.domain; + +public class Person { + + private final String name; + private final int age; + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/logging/LoggingAspect.java b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/logging/LoggingAspect.java new file mode 100644 index 00000000..e77adb73 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/logging/LoggingAspect.java @@ -0,0 +1,17 @@ +package ru.otus.spring.logging; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; + +@Aspect +public class LoggingAspect { + + @Before("execution(* ru.otus.spring.dao.PersonDaoSimple.*(..))") + public void logBefore(JoinPoint joinPoint) { + System.out.println("Прокси : " + joinPoint.getThis().getClass().getName()); + System.out.println("Класс : " + joinPoint.getTarget().getClass().getName()); + + System.out.println("Вызов метода : " + joinPoint.getSignature().getName()); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/service/PersonService.java b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/service/PersonService.java new file mode 100644 index 00000000..9b83e7de --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/service/PersonService.java @@ -0,0 +1,8 @@ +package ru.otus.spring.service; + +import ru.otus.spring.domain.Person; + +public interface PersonService { + + Person getByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/service/PersonServiceImpl.java b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/service/PersonServiceImpl.java new file mode 100644 index 00000000..e6ee475f --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ctw/src/main/java/ru/otus/spring/service/PersonServiceImpl.java @@ -0,0 +1,20 @@ +package ru.otus.spring.service; + +import org.springframework.stereotype.Service; +import ru.otus.spring.dao.PersonDao; +import ru.otus.spring.domain.Person; + +@Service +public class PersonServiceImpl implements PersonService { + + private final PersonDao dao; + + public PersonServiceImpl(PersonDao dao) { + this.dao = dao; + } + + @Override + public Person getByName(String name) { + return dao.findByName(name); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/pom.xml b/2025-11/spring-04-aop/aop-demo/aop-custom/pom.xml new file mode 100644 index 00000000..26654a5c --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + ru.otus + aop-custom + 1.0 + + + UTF-8 + 17 + 17 + 6.0.9 + 1.9.19 + + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + + org.springframework + spring-context + ${spring.version} + + + + diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/Main.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/Main.java new file mode 100644 index 00000000..0e1122f5 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/Main.java @@ -0,0 +1,69 @@ +package ru.otus.demo; + +import ru.otus.demo.aop.LoggingAspect; +import ru.otus.demo.aop.SimpleWeaver; +import ru.otus.demo.dao.BookDao; +import ru.otus.demo.dao.BookDaoSimple; +import ru.otus.demo.dao.PersonDao; +import ru.otus.demo.dao.PersonDaoSimple; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Main { + + public static void main(String[] args) { + + // Как будто Bean Definitions + List> beanDefinitions = List.of(SimpleWeaver.class, LoggingAspect.class, + PersonDaoSimple.class, BookDaoSimple.class); + + // Как будто контекст + Map, Object> context = new HashMap<>(); + beanDefinitions.stream() + // Создание бинов + .map(Main::createInstance) + // Постобработка, вивинг + .forEach(bean -> putBeanIntoContextAndApplyAspectIfNecessary(bean, context)); + + // Как будто достаем из контекста дао (уже с примененным аспектом) + PersonDao personDaoProxy = (PersonDao) context.get(PersonDao.class); + BookDao bookDaoProxy = (BookDao) context.get(BookDao.class); + + // Используем сервисы + personDaoProxy.findByName("Вася"); + System.out.println("-------------------------------------------------"); + bookDaoProxy.findByTitle("Укротители велосипедов"); + } + + private static Object createInstance(Class clazz) { + try { + return clazz.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static Class getInterfaceOrClass(Object o) { + if (o.getClass().getInterfaces().length > 0) { + return o.getClass().getInterfaces()[0]; + } + return o.getClass(); + } + + private static void putBeanIntoContextAndApplyAspectIfNecessary(Object bean, Map, Object> context) { + // Если нет интерфейсов, то это наш вивер и аспект. Просто кладем в контекст + // (сам спринг естественно не такие штуки ориентируется, но у нас будет такое допущение) + Class key = getInterfaceOrClass(bean); + if (!key.isInterface()) { + context.put(key, bean); + return; + } + + // Если интерфейсы есть, то это наши дао и мы их вивим с аспектом. Результат кладем в контекст + SimpleWeaver weaver = (SimpleWeaver) context.get(SimpleWeaver.class); + LoggingAspect aspect = (LoggingAspect) context.get(LoggingAspect.class); + context.put(key, weaver.weave(bean, aspect)); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/MainSimple.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/MainSimple.java new file mode 100644 index 00000000..e24ab0b7 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/MainSimple.java @@ -0,0 +1,67 @@ +package ru.otus.demo; + +import org.springframework.cglib.proxy.Enhancer; +import ru.otus.demo.dao.PersonDao; +import ru.otus.demo.dao.PersonDaoSimple; +import ru.otus.demo.service.PersonService; +import ru.otus.demo.service.PersonServiceImpl; + +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public class MainSimple { + + public static void main(String[] args) { + + LoggingAspectSimple aspect = new LoggingAspectSimple(); + + PersonDao personDaoSimple = new PersonDaoSimple(); + + // JdkProxy + System.out.println("JdkProxy"); + PersonDao personDaoJdkProxy = (PersonDao) Proxy.newProxyInstance( + MainSimple.class.getClassLoader(), + personDaoSimple.getClass().getInterfaces(), + new java.lang.reflect.InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] methodArgs) throws Throwable { + aspect.logBefore(personDaoSimple.getClass(), proxy.getClass(), method, methodArgs); + return method.invoke(personDaoSimple, methodArgs); + } + } + ); + PersonService personService = new PersonServiceImpl(personDaoJdkProxy); + personService.getByName("Вася"); + + + // CglibProxy (Spring edition, работает в Java 17 без плясок) + System.out.println("\n\nCglibProxy (Spring edition)"); + Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(PersonDaoSimple.class); + enhancer.setCallback(new org.springframework.cglib.proxy.InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] methodArgs) throws Throwable { + aspect.logBefore(personDaoSimple.getClass(), proxy.getClass(), method, methodArgs); + return method.invoke(personDaoSimple, methodArgs); + } + }); + PersonDao personDaoCgLibProxy = (PersonDao) enhancer.create(); + personService = new PersonServiceImpl(personDaoCgLibProxy); + personService.getByName("Игорь"); + } + + private static class LoggingAspectSimple { + public void logBefore(Class originalClass, Class proxyClass, Method method, Object[] methodArgs) { + System.out.println("Прокси : " + proxyClass.getName()); + System.out.println("Класс : " + originalClass.getName()); + + System.out.println("Вызов метода : " + method.getName()); + System.out.println("Аргументы метода : " + Arrays.stream(methodArgs) + .map(Objects::toString) + .collect(Collectors.joining(", "))); + } + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/LoggingAspect.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/LoggingAspect.java new file mode 100644 index 00000000..e8537435 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/LoggingAspect.java @@ -0,0 +1,20 @@ +package ru.otus.demo.aop; + +import org.aspectj.lang.JoinPoint; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public class LoggingAspect { + + public void logBefore(JoinPoint joinPoint) { + System.out.println("Прокси : " + joinPoint.getThis().getClass().getName()); + System.out.println("Класс : " + joinPoint.getTarget().getClass().getName()); + + System.out.println("Вызов метода : " + joinPoint.getSignature().getName()); + System.out.println("Аргументы метода : " + Arrays.stream(joinPoint.getArgs()) + .map(Objects::toString) + .collect(Collectors.joining(", "))); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleAOPInvocationHandler.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleAOPInvocationHandler.java new file mode 100644 index 00000000..c95cd290 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleAOPInvocationHandler.java @@ -0,0 +1,24 @@ +package ru.otus.demo.aop; + +import org.aspectj.lang.JoinPoint; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +public class SimpleAOPInvocationHandler implements InvocationHandler { + private final Object target; + private final LoggingAspect aspect; + + public SimpleAOPInvocationHandler(Object target, LoggingAspect aspect) { + this.target = target; + this.aspect = aspect; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + JoinPoint joinPoint = new SimpleJoinPoint(target, + proxy, args, method); + aspect.logBefore(joinPoint); + return method.invoke(target, args); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleJoinPoint.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleJoinPoint.java new file mode 100644 index 00000000..26260948 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleJoinPoint.java @@ -0,0 +1,67 @@ +package ru.otus.demo.aop; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.reflect.SourceLocation; + +import java.lang.reflect.Method; + +public class SimpleJoinPoint implements JoinPoint { + private final Object targetClass; + private final Object proxyClass; + private final Object[] args; + private final Signature targetMethodSignature; + + public SimpleJoinPoint(Object target, Object proxy, Object[] args, + Method targetMethod) { + this.targetClass = target; + this.proxyClass = proxy; + this.args = args; + this.targetMethodSignature = new SimpleSignature(targetMethod); + } + + @Override + public String toShortString() { + throw new UnsupportedOperationException(); + } + + @Override + public String toLongString() { + throw new UnsupportedOperationException(); + } + + @Override + public Object getThis() { + return proxyClass; + } + + @Override + public Object getTarget() { + return targetClass; + } + + @Override + public Object[] getArgs() { + return args; + } + + @Override + public Signature getSignature() { + return targetMethodSignature; + } + + @Override + public SourceLocation getSourceLocation() { + throw new UnsupportedOperationException(); + } + + @Override + public String getKind() { + throw new UnsupportedOperationException(); + } + + @Override + public StaticPart getStaticPart() { + throw new UnsupportedOperationException(); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleSignature.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleSignature.java new file mode 100644 index 00000000..9699e595 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleSignature.java @@ -0,0 +1,43 @@ +package ru.otus.demo.aop; + +import org.aspectj.lang.Signature; + +import java.lang.reflect.Method; + +public class SimpleSignature implements Signature { + private final Method targetMethod; + + public SimpleSignature(Method targetMethod) { + this.targetMethod = targetMethod; + } + + @Override + public String toShortString() { + throw new UnsupportedOperationException(); + } + + @Override + public String toLongString() { + throw new UnsupportedOperationException(); + } + + @Override + public String getName() { + return targetMethod.getName(); + } + + @Override + public int getModifiers() { + throw new UnsupportedOperationException(); + } + + @Override + public Class getDeclaringType() { + throw new UnsupportedOperationException(); + } + + @Override + public String getDeclaringTypeName() { + throw new UnsupportedOperationException(); + } +} \ No newline at end of file diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleWeaver.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleWeaver.java new file mode 100644 index 00000000..4b3a64a6 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/aop/SimpleWeaver.java @@ -0,0 +1,16 @@ +package ru.otus.demo.aop; + +import ru.otus.demo.Main; + +import java.lang.reflect.Proxy; + +public class SimpleWeaver { + @SuppressWarnings("unchecked") + public T weave(T classInstance, LoggingAspect aspect) { + return (T) Proxy.newProxyInstance( + Main.class.getClassLoader(), + classInstance.getClass().getInterfaces(), + new SimpleAOPInvocationHandler(classInstance, aspect) + ); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/BookDao.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/BookDao.java new file mode 100644 index 00000000..17a905ba --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/BookDao.java @@ -0,0 +1,8 @@ +package ru.otus.demo.dao; + +import ru.otus.demo.domain.Book; + +public interface BookDao { + + Book findByTitle(String title); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/BookDaoSimple.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/BookDaoSimple.java new file mode 100644 index 00000000..9c039121 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/BookDaoSimple.java @@ -0,0 +1,10 @@ +package ru.otus.demo.dao; + +import ru.otus.demo.domain.Book; + +public class BookDaoSimple implements BookDao { + @Override + public Book findByTitle(String title) { + return new Book(title); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/PersonDao.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/PersonDao.java new file mode 100644 index 00000000..15563d64 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/PersonDao.java @@ -0,0 +1,8 @@ +package ru.otus.demo.dao; + +import ru.otus.demo.domain.Person; + +public interface PersonDao { + + Person findByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/PersonDaoSimple.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/PersonDaoSimple.java new file mode 100644 index 00000000..cca909a9 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/dao/PersonDaoSimple.java @@ -0,0 +1,12 @@ +package ru.otus.demo.dao; + +import ru.otus.demo.domain.Person; + + +public class PersonDaoSimple implements PersonDao { + + @Override + public Person findByName(String name) { + return new Person(name, 18); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/domain/Book.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/domain/Book.java new file mode 100644 index 00000000..25c096a8 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/domain/Book.java @@ -0,0 +1,5 @@ +package ru.otus.demo.domain; + +public record Book(String title) { + +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/domain/Person.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/domain/Person.java new file mode 100644 index 00000000..6726c868 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/domain/Person.java @@ -0,0 +1,12 @@ +package ru.otus.demo.domain; + +public record Person(String name, int age) { + + @Override + public String toString() { + return "Person{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/BookService.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/BookService.java new file mode 100644 index 00000000..713e4e82 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/BookService.java @@ -0,0 +1,8 @@ +package ru.otus.demo.service; + +import ru.otus.demo.domain.Book; + +public interface BookService { + + Book getByTitle(String title); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/BookServiceImpl.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/BookServiceImpl.java new file mode 100644 index 00000000..836572ce --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/BookServiceImpl.java @@ -0,0 +1,17 @@ +package ru.otus.demo.service; + +import ru.otus.demo.dao.BookDao; +import ru.otus.demo.domain.Book; + +public class BookServiceImpl implements BookService { + private final BookDao bookDao; + + public BookServiceImpl(BookDao bookDao) { + this.bookDao = bookDao; + } + + @Override + public Book getByTitle(String title) { + return bookDao.findByTitle(title); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/PersonService.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/PersonService.java new file mode 100644 index 00000000..5a3ae9ab --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/PersonService.java @@ -0,0 +1,8 @@ +package ru.otus.demo.service; + +import ru.otus.demo.domain.Person; + +public interface PersonService { + + Person getByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/PersonServiceImpl.java b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/PersonServiceImpl.java new file mode 100644 index 00000000..b15ab470 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-custom/src/main/java/ru/otus/demo/service/PersonServiceImpl.java @@ -0,0 +1,18 @@ +package ru.otus.demo.service; + +import ru.otus.demo.dao.PersonDao; +import ru.otus.demo.domain.Person; + +public class PersonServiceImpl implements PersonService { + + private final PersonDao dao; + + public PersonServiceImpl(PersonDao dao) { + this.dao = dao; + } + + @Override + public Person getByName(String name) { + return dao.findByName(name); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ltw/exec.sh b/2025-11/spring-04-aop/aop-demo/aop-ltw/exec.sh new file mode 100644 index 00000000..481a1b67 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ltw/exec.sh @@ -0,0 +1,3 @@ +mvn clean package +java -javaagent:c:/Users/User/.m2/repository/org/aspectj/aspectjweaver/1.9.19/aspectjweaver-1.9.19.jar -jar target/aop-ltw-1.0-jar-with-dependencies.jar +read -p "Press enter to continue" \ No newline at end of file diff --git a/2025-11/spring-04-aop/aop-demo/aop-ltw/pom.xml b/2025-11/spring-04-aop/aop-demo/aop-ltw/pom.xml new file mode 100644 index 00000000..76886f9d --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ltw/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + ru.otus + aop-ltw + 1.0 + + + UTF-8 + 17 + 17 + 6.0.9 + 1.9.19 + + + + + org.springframework + spring-context + ${spring.version} + + + + + org.springframework + spring-aop + ${spring.version} + + + + org.springframework + spring-instrument + ${spring.version} + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + jar-with-dependencies + + + + ru.otus.spring.Main + + + + + + make-assembly + package + + single + + + + + + + diff --git a/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/Main.java b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..2e5103d9 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,31 @@ +package ru.otus.spring; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import ru.otus.spring.domain.Person; +import ru.otus.spring.service.PersonService; + +/* +Запуск примера: + 1. В IDEA, вменю запуска выбираем "Edit Configurations..." + 2. В поле "VM options" вносим "-javaagent:${путь.до.m2}\.m2\repository\org\aspectj\aspectjweaver\1.9.8\aspectjweaver-1.9.8.jar", + где ${путь.до.m2} это путь до репозитория мавен на текущем компьютере. + Пример: "-javaagent:c:\Users\MyUserName\.m2\repository\org\aspectj\aspectjweaver\1.9.9.1\aspectjweaver-1.9.9.1.jar". + Кавычки не вносим) + 3. Запускаем Main +*/ + +@Configuration +@ComponentScan +public class Main { + public static void main(String[] args) { + AnnotationConfigApplicationContext context = + new AnnotationConfigApplicationContext(Main.class); + + PersonService service = context.getBean(PersonService.class); + + Person ivan = service.getByName("Ivan"); + System.out.println("name: " + ivan.name() + " age: " + ivan.age()); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/dao/PersonDao.java b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/dao/PersonDao.java new file mode 100644 index 00000000..d33939bd --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/dao/PersonDao.java @@ -0,0 +1,8 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public interface PersonDao { + + Person findByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java new file mode 100644 index 00000000..8ffbcf41 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java @@ -0,0 +1,16 @@ +package ru.otus.spring.dao; + +import org.springframework.stereotype.Repository; +import ru.otus.spring.domain.Person; + +@Repository +public class PersonDaoSimple implements PersonDao { + public PersonDaoSimple() { + System.out.println(this.getClass().getClassLoader()); + } + + @Override + public Person findByName(String name) { + return new Person(name, 18); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/domain/Person.java b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..9ba649d1 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,5 @@ +package ru.otus.spring.domain; + +public record Person(String name, int age) { + +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/logging/LoggingAspect.java b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/logging/LoggingAspect.java new file mode 100644 index 00000000..e77adb73 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/logging/LoggingAspect.java @@ -0,0 +1,17 @@ +package ru.otus.spring.logging; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; + +@Aspect +public class LoggingAspect { + + @Before("execution(* ru.otus.spring.dao.PersonDaoSimple.*(..))") + public void logBefore(JoinPoint joinPoint) { + System.out.println("Прокси : " + joinPoint.getThis().getClass().getName()); + System.out.println("Класс : " + joinPoint.getTarget().getClass().getName()); + + System.out.println("Вызов метода : " + joinPoint.getSignature().getName()); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/service/PersonService.java b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/service/PersonService.java new file mode 100644 index 00000000..9b83e7de --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/service/PersonService.java @@ -0,0 +1,8 @@ +package ru.otus.spring.service; + +import ru.otus.spring.domain.Person; + +public interface PersonService { + + Person getByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/service/PersonServiceImpl.java b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/service/PersonServiceImpl.java new file mode 100644 index 00000000..e6ee475f --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/java/ru/otus/spring/service/PersonServiceImpl.java @@ -0,0 +1,20 @@ +package ru.otus.spring.service; + +import org.springframework.stereotype.Service; +import ru.otus.spring.dao.PersonDao; +import ru.otus.spring.domain.Person; + +@Service +public class PersonServiceImpl implements PersonService { + + private final PersonDao dao; + + public PersonServiceImpl(PersonDao dao) { + this.dao = dao; + } + + @Override + public Person getByName(String name) { + return dao.findByName(name); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/resources/META-INF/aop.xml b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/resources/META-INF/aop.xml new file mode 100644 index 00000000..adf0ac99 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-ltw/src/main/resources/META-INF/aop.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/2025-11/spring-04-aop/aop-demo/aop-native/pom.xml b/2025-11/spring-04-aop/aop-demo/aop-native/pom.xml new file mode 100644 index 00000000..e967f24d --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-native/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + ru.otus + aop-native + 1.0 + + + UTF-8 + 17 + 17 + 6.0.9 + 1.9.19 + + + + + org.springframework + spring-context + ${spring.version} + + + + org.springframework + spring-aop + ${spring.version} + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + diff --git a/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/Main.java b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..dcac9032 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,22 @@ +package ru.otus.spring; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import ru.otus.spring.domain.Person; +import ru.otus.spring.service.PersonService; + +@Configuration +@ComponentScan +public class Main { + + public static void main(String[] args) { + AnnotationConfigApplicationContext context = + new AnnotationConfigApplicationContext(Main.class); + + PersonService service = context.getBean(PersonService.class); + + Person ivan = service.getByName("Ivan"); + System.out.println("name: " + ivan.name() + " age: " + ivan.age()); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/config/CommonNativeAopConfig.java b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/config/CommonNativeAopConfig.java new file mode 100644 index 00000000..cb9f6bc2 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/config/CommonNativeAopConfig.java @@ -0,0 +1,17 @@ +package ru.otus.spring.config; + +import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Role; + +import static org.springframework.beans.factory.config.BeanDefinition.ROLE_INFRASTRUCTURE; + +@Role(ROLE_INFRASTRUCTURE) +@Configuration +public class CommonNativeAopConfig { + @Bean + public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { + return new DefaultAdvisorAutoProxyCreator(); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/config/LoggingAspectConfig.java b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/config/LoggingAspectConfig.java new file mode 100644 index 00000000..20d79ce9 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/config/LoggingAspectConfig.java @@ -0,0 +1,39 @@ +package ru.otus.spring.config; + +import org.springframework.aop.ClassFilter; +import org.springframework.aop.MethodBeforeAdvice; +import org.springframework.aop.MethodMatcher; +import org.springframework.aop.Pointcut; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.otus.spring.dao.PersonDaoSimple; + +@Configuration +public class LoggingAspectConfig { + + public Pointcut personDaoSimpleLoggingAspectPointcut() { + return new Pointcut() { + @Override + public ClassFilter getClassFilter() { + return clazz -> clazz.equals(PersonDaoSimple.class); + } + + @Override + public MethodMatcher getMethodMatcher() { + return MethodMatcher.TRUE; + } + }; + } + + MethodBeforeAdvice personDaoSimpleLoggingAspectBeforeAdvice() { + return (method, objects, o) -> System.out.println("Ура! Вызов метода : " + method.getName()); + } + + + @Bean + public DefaultPointcutAdvisor personDaoSimpleLoggingAspectAdvisor() { + return new DefaultPointcutAdvisor(personDaoSimpleLoggingAspectPointcut(), + personDaoSimpleLoggingAspectBeforeAdvice()); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/dao/PersonDao.java b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/dao/PersonDao.java new file mode 100644 index 00000000..d33939bd --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/dao/PersonDao.java @@ -0,0 +1,8 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public interface PersonDao { + + Person findByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java new file mode 100644 index 00000000..b39e82b5 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java @@ -0,0 +1,13 @@ +package ru.otus.spring.dao; + +import org.springframework.stereotype.Repository; +import ru.otus.spring.domain.Person; + +@Repository +public class PersonDaoSimple implements PersonDao { + + @Override + public Person findByName(String name) { + return new Person(name, 18); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/domain/Person.java b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..9ba649d1 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,5 @@ +package ru.otus.spring.domain; + +public record Person(String name, int age) { + +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/service/PersonService.java b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/service/PersonService.java new file mode 100644 index 00000000..9b83e7de --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/service/PersonService.java @@ -0,0 +1,8 @@ +package ru.otus.spring.service; + +import ru.otus.spring.domain.Person; + +public interface PersonService { + + Person getByName(String name); +} diff --git a/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/service/PersonServiceImpl.java b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/service/PersonServiceImpl.java new file mode 100644 index 00000000..e6ee475f --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/aop-native/src/main/java/ru/otus/spring/service/PersonServiceImpl.java @@ -0,0 +1,20 @@ +package ru.otus.spring.service; + +import org.springframework.stereotype.Service; +import ru.otus.spring.dao.PersonDao; +import ru.otus.spring.domain.Person; + +@Service +public class PersonServiceImpl implements PersonService { + + private final PersonDao dao; + + public PersonServiceImpl(PersonDao dao) { + this.dao = dao; + } + + @Override + public Person getByName(String name) { + return dao.findByName(name); + } +} diff --git a/2025-11/spring-04-aop/aop-demo/pom.xml b/2025-11/spring-04-aop/aop-demo/pom.xml new file mode 100644 index 00000000..8828cdf6 --- /dev/null +++ b/2025-11/spring-04-aop/aop-demo/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + ru.otus + aop-demo + 1.0 + + pom + + + aop-ctw + aop-ctw-plain + aop-custom + aop-ltw + aop-native + +