Как указано в моем комментарии: почти во всех случаях более желательно использовать соответствующий шаблон проектирования, чем начинать полагаться на такие вещи, как динамические прокси , отражение или AOP для решения такого рода проблем.
При этом вопрос задает вопрос: возможно ли 1010 * модифицировать функции Kotlin во время компиляции посредством метапрограммирования, и ответом является "Да" . Для демонстрации ниже приведен полный пример, который использует AspectJ .
Структура проекта
Я создал небольшой Maven проект со следующей структурой:
.
├── pom.xml
└── src
└── main
└── kotlin
├── Aop.kt
└── Main.kt
Я воспроизведу содержимое всех файлов в следующих разделах.
Код приложения
Фактический код приложения находится в файле с именем Main.kt
, и - за исключением того факта, что я переименовал вашу функцию, чтобы она соответствовала Правилам именования Kotlin - это идентично к коду, указанному в вашем вопросе. Метод getNumber()
предназначен для возврата 3 .
fun main(args: Array<String>) {
println(getNumber())
}
fun getNumber(): Int {
return 3
}
AOP код
Код, связанный с AOP, находится в Aop.kt
и очень прост. Он имеет совет @Around
с точечным вырезом, который соответствует выполнению функции getNumber()
. Совет перехватит вызов метода getNumber()
и вернет 42 (вместо 3 ).
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
@Aspect
class Aop {
@Around("execution(* MainKt.getNumber(..))")
fun getRealNumber(joinPoint: ProceedingJoinPoint): Any {
return 42
}
}
(Обратите внимание, что имя сгенерированного класса для файла Main.kt
равно MainKt
.)
POM файл
Файл POM объединяет все. Я использую 4 плагина:
Это полный файл POM:
<?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>x.y.z</groupId>
<artifactId>kotlin-aop</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<kotlin.version>1.2.61</kotlin.version>
<aspectj.version>1.9.1</aspectj.version>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal>
</goals>
</execution>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-maven-plugin</artifactId>
<version>0.14.1</version>
<executions>
<execution>
<goals>
<goal>ajc</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>MainKt</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Сборка и выполнение
Для сборки, как и в любом проекте Maven, вам просто нужно запустить:
mvn clean package
Это создаст толстый JAR в target/kotlin-aop-1.0-SNAPSHOT.jar
месте. Затем этот JAR-файл можно выполнить с помощью команды java
:
java -jar target/kotlin-aop-1.0-SNAPSHOT.jar
Затем выполнение дает нам следующий результат, демонстрирующий, что все работает как ожидалось:
42
(Приложение было создано и выполнено с использованием самой последней версии Oracle Java 8 JDK на момент написания статьи - 1.8.0_181)
Заключение
Как показывает приведенный выше пример, безусловно, можно переопределить функции Kotlin, но, повторяя мою первоначальную точку зрения, почти во всех случаях существуют более элегантные решения для достижения того, что вам нужно.