mirror of
https://github.com/OtusTeam/Spring.git
synced 2026-05-30 10:50:42 +00:00
2024-05 spring-04-aop
This commit is contained in:
@@ -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/
|
||||
@@ -0,0 +1,42 @@
|
||||
<?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>exercise</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<spring.version>6.0.9</spring.version>
|
||||
|
||||
<aspectj.version>1.9.19</aspectj.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- можно не писать - она транзитивна spring-context -->
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<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,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.getName() + " age: " + ivan.getAge());
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.dao;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonDao {
|
||||
|
||||
Person findByName(String name);
|
||||
}
|
||||
+14
@@ -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);
|
||||
}
|
||||
}
|
||||
+20
@@ -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;
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.service;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonService {
|
||||
|
||||
Person getByName(String name);
|
||||
}
|
||||
+21
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?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-classwork</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>exercise</module>
|
||||
<module>solution</module>
|
||||
</modules>
|
||||
</project>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?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>solution</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<spring.version>6.0.9</spring.version>
|
||||
|
||||
<aspectj.version>1.9.19</aspectj.version>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- можно не писать - она транзитивна spring-context -->
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<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,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.getName() + " age: " + ivan.getAge());
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.dao;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonDao {
|
||||
|
||||
Person findByName(String name);
|
||||
}
|
||||
+16
@@ -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);
|
||||
}
|
||||
}
|
||||
+20
@@ -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;
|
||||
}
|
||||
}
|
||||
+11
@@ -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 {
|
||||
}
|
||||
+19
@@ -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());
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.service;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonService {
|
||||
|
||||
Person getByName(String name);
|
||||
}
|
||||
+21
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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/
|
||||
@@ -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"
|
||||
@@ -0,0 +1,93 @@
|
||||
<?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-ctw-plain</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<aspectj.version>1.9.19</aspectj.version>
|
||||
<aspectj.plugin.version>1.13.1</aspectj.plugin.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>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.aspectj</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>${aspectj.plugin.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>ru.otus.spring.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>dev.aspectj</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>${aspectj.plugin.version}</version>
|
||||
<configuration>
|
||||
<complianceLevel>17</complianceLevel>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
<showWeaveInfo>true</showWeaveInfo>
|
||||
<verbose>true</verbose>
|
||||
<Xlint>ignore</Xlint>
|
||||
<encoding>UTF-8</encoding>
|
||||
<weaveDirectories>
|
||||
<weaveDirectory>${project.build.directory}/classes</weaveDirectory>
|
||||
</weaveDirectories>
|
||||
<forceAjcCompile>true</forceAjcCompile>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<!-- <goal>test-compile</goal> -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -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.getName() + " age: " + ivan.getAge());
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.dao;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonDao {
|
||||
|
||||
Person findByName(String name);
|
||||
}
|
||||
+11
@@ -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);
|
||||
}
|
||||
}
|
||||
+20
@@ -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;
|
||||
}
|
||||
}
|
||||
+17
@@ -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());
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.service;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonService {
|
||||
|
||||
Person getByName(String name);
|
||||
}
|
||||
+18
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mvn clean package
|
||||
java -jar target/aop-ctw-1.0-jar-with-dependencies.jar
|
||||
read -p "Press enter to continue"
|
||||
@@ -0,0 +1,104 @@
|
||||
<?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-ctw</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<spring.version>6.0.9</spring.version>
|
||||
<aspectj.version>1.9.19</aspectj.version>
|
||||
<aspectj.plugin.version>1.13.1</aspectj.plugin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- можно не писать - она транзитивна spring-context -->
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<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>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.aspectj</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>${aspectj.plugin.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>ru.otus.spring.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>dev.aspectj</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>${aspectj.plugin.version}</version>
|
||||
<configuration>
|
||||
<complianceLevel>17</complianceLevel>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
<showWeaveInfo>true</showWeaveInfo>
|
||||
<verbose>true</verbose>
|
||||
<Xlint>ignore</Xlint>
|
||||
<encoding>UTF-8</encoding>
|
||||
<weaveDirectories>
|
||||
<weaveDirectory>${project.build.directory}/classes</weaveDirectory>
|
||||
</weaveDirectories>
|
||||
<forceAjcCompile>true</forceAjcCompile>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<!-- <goal>test-compile</goal> -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,30 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.dao;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonDao {
|
||||
|
||||
Person findByName(String name);
|
||||
}
|
||||
+14
@@ -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);
|
||||
}
|
||||
}
|
||||
+20
@@ -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;
|
||||
}
|
||||
}
|
||||
+17
@@ -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());
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.service;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonService {
|
||||
|
||||
Person getByName(String name);
|
||||
}
|
||||
+21
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?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>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<spring.version>6.0.9</spring.version>
|
||||
<aspectj.version>1.9.19</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>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,69 @@
|
||||
package ru.otus.demo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Как будто Bean Definitions
|
||||
List<Class<?>> beanDefinitions = List.of(SimpleWeaver.class, LoggingAspect.class,
|
||||
PersonDaoSimple.class, BookDaoSimple.class);
|
||||
|
||||
// Как будто контекст
|
||||
Map<Class<?>, 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<Class<?>, 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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package ru.otus.demo;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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;
|
||||
|
||||
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(", ")));
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package ru.otus.demo.aop;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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());
|
||||
System.out.println("Аргументы метода : " + Arrays.stream(joinPoint.getArgs())
|
||||
.map(Objects::toString)
|
||||
.collect(Collectors.joining(", ")));
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package ru.otus.demo.aop;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package ru.otus.demo.aop;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
import org.aspectj.lang.reflect.SourceLocation;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package ru.otus.demo.aop;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.Signature;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package ru.otus.demo.aop;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import ru.otus.demo.Main;
|
||||
|
||||
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);
|
||||
}
|
||||
+10
@@ -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);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.demo.dao;
|
||||
|
||||
import ru.otus.demo.domain.Person;
|
||||
|
||||
public interface PersonDao {
|
||||
|
||||
Person findByName(String name);
|
||||
}
|
||||
+12
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package ru.otus.demo.domain;
|
||||
|
||||
public class Book {
|
||||
|
||||
private final String title;
|
||||
|
||||
public Book(String name) {
|
||||
this.title = name;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package ru.otus.demo.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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Person{" +
|
||||
"name='" + name + '\'' +
|
||||
", age=" + age +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.demo.service;
|
||||
|
||||
import ru.otus.demo.domain.Book;
|
||||
|
||||
public interface BookService {
|
||||
|
||||
Book getByTitle(String title);
|
||||
}
|
||||
+17
@@ -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);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.demo.service;
|
||||
|
||||
import ru.otus.demo.domain.Person;
|
||||
|
||||
public interface PersonService {
|
||||
|
||||
Person getByName(String name);
|
||||
}
|
||||
+18
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
@@ -0,0 +1,80 @@
|
||||
<?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-ltw</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<spring.version>6.0.9</spring.version>
|
||||
<aspectj.version>1.9.19</aspectj.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- можно не писать - она транзитивна spring-context -->
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-instrument</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<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>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>ru.otus.spring.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,32 @@
|
||||
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.getName() + " age: " + ivan.getAge());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.dao;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonDao {
|
||||
|
||||
Person findByName(String name);
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
+20
@@ -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;
|
||||
}
|
||||
}
|
||||
+17
@@ -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());
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.service;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonService {
|
||||
|
||||
Person getByName(String name);
|
||||
}
|
||||
+21
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
|
||||
<aspectj>
|
||||
|
||||
<weaver options="-showWeaveInfo -verbose">
|
||||
<include within="ru.otus.spring.dao.*"/>
|
||||
<include within="ru.otus.spring.logging.*"/>
|
||||
</weaver>
|
||||
|
||||
<aspects>
|
||||
<aspect name="ru.otus.spring.logging.LoggingAspect"/>
|
||||
</aspects>
|
||||
|
||||
</aspectj>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?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-native</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<spring.version>6.0.9</spring.version>
|
||||
<aspectj.version>1.9.19</aspectj.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- можно не писать - она транзитивна spring-context -->
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<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,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.getName() + " age: " + ivan.getAge());
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package ru.otus.spring.config;
|
||||
|
||||
import static org.springframework.beans.factory.config.BeanDefinition.ROLE_INFRASTRUCTURE;
|
||||
|
||||
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;
|
||||
|
||||
@Role(ROLE_INFRASTRUCTURE)
|
||||
@Configuration
|
||||
public class CommonNativeAopConfig {
|
||||
@Bean
|
||||
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
|
||||
return new DefaultAdvisorAutoProxyCreator();
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.dao;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonDao {
|
||||
|
||||
Person findByName(String name);
|
||||
}
|
||||
+14
@@ -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);
|
||||
}
|
||||
}
|
||||
+20
@@ -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;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.spring.service;
|
||||
|
||||
import ru.otus.spring.domain.Person;
|
||||
|
||||
public interface PersonService {
|
||||
|
||||
Person getByName(String name);
|
||||
}
|
||||
+21
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?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-demo</artifactId>
|
||||
<version>1.0</version>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>aop-ctw</module>
|
||||
<module>aop-ctw-plain</module>
|
||||
<module>aop-custom</module>
|
||||
<module>aop-ltw</module>
|
||||
<module>aop-native</module>
|
||||
</modules>
|
||||
</project>
|
||||
Reference in New Issue
Block a user