2022-02 aop-demo updated

This commit is contained in:
stvort
2022-03-12 15:01:49 +04:00
parent 027e858c80
commit 6a1116ff7e
18 changed files with 369 additions and 0 deletions
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.otus</groupId>
<artifactId>aop-custom</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<aspectj.version>1.9.8</aspectj.version>
</properties>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,47 @@
package ru.otus.demo;
import ru.otus.demo.aop.LoggingAspect;
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 ru.otus.demo.service.BookService;
import ru.otus.demo.service.BookServiceImpl;
import ru.otus.demo.service.PersonService;
import ru.otus.demo.service.PersonServiceImpl;
import ru.otus.demo.aop.SimpleWeaver;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
SimpleWeaver weaver = new SimpleWeaver();
LoggingAspect aspect = new LoggingAspect();
// Как будто контекст с бинами (пока без аспекта)
Map<Class<?>, Object> context = new HashMap<>();
context.put(PersonDao.class, new PersonDaoSimple());
context.put(BookDao.class, new BookDaoSimple());
// Колхозный вивинг
context.forEach((key, value) -> context.put(key, weaver.weave(value, aspect)));
// Как будто достаем из контекста дао (уже с примененным аспектом)
PersonDao personDaoProxy = (PersonDao) context.get(PersonDao.class);
BookDao bookDaoProxy = (BookDao) context.get(BookDao.class);
// Внедряем в сервисы
PersonService personService = new PersonServiceImpl(personDaoProxy);
BookService bookService = new BookServiceImpl(bookDaoProxy);
// Используем сервисы
personService.getByName("Вася");
System.out.println("-------------------------------------------------");
bookService.getByTitle("Укротители велосипедов");
}
}
@@ -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(", ")));
}
}
@@ -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);
}
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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> T weave(T classInstance, LoggingAspect aspect) {
return (T) Proxy.newProxyInstance(
Main.class.getClassLoader(),
classInstance.getClass().getInterfaces(),
new SimpleAOPInvocationHandler(classInstance, aspect)
);
}
}
@@ -0,0 +1,8 @@
package ru.otus.demo.dao;
import ru.otus.demo.domain.Book;
public interface BookDao {
Book findByTitle(String title);
}
@@ -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);
}
}
@@ -0,0 +1,8 @@
package ru.otus.demo.dao;
import ru.otus.demo.domain.Person;
public interface PersonDao {
Person findByName(String name);
}
@@ -0,0 +1,11 @@
package ru.otus.demo.dao;
import ru.otus.demo.domain.Person;
public class PersonDaoSimple implements PersonDao {
public Person findByName(String name) {
return new Person(name, 18);
}
}
@@ -0,0 +1,14 @@
package ru.otus.demo.domain;
public class Book {
private String title;
public Book(String name) {
this.title = name;
}
public String getTitle() {
return title;
}
}
@@ -0,0 +1,20 @@
package ru.otus.demo.domain;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
@@ -0,0 +1,8 @@
package ru.otus.demo.service;
import ru.otus.demo.domain.Book;
public interface BookService {
Book getByTitle(String title);
}
@@ -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);
}
}
@@ -0,0 +1,8 @@
package ru.otus.demo.service;
import ru.otus.demo.domain.Person;
public interface PersonService {
Person getByName(String name);
}
@@ -0,0 +1,17 @@
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;
}
public Person getByName(String name) {
return dao.findByName(name);
}
}
+1
View File
@@ -13,6 +13,7 @@
<modules>
<module>aop-ctw</module>
<module>aop-ctw-plain</module>
<module>aop-custom</module>
<module>aop-ltw</module>
<module>aop-native</module>
</modules>