Автоматическая проверка условий в методах класса Java

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Сложность этой задачи можно обойти с помощью Аспектно-ориентированного программирования (AOP) с применением AspectJ. С его помощью код можно вставлять автоматически перед исполнением методов в классе. Пример использования выглядит так:

Java
Скопировать код
@Aspect
public class ВашиДействияAspect {

    @Before("execution(* ВашЦелевойКласс.*(..))")
    public void сделатьПредварительноКод() {
        // Код, который будет работать перед каждым методом в классе
        System.out.println("Привет, это выполнено перед методом.");
    }
}

Связывание вашего аспекта с классом обеспечивает автоматическую реализацию выбранных вами действий перед каждым методом.

Кинга Идем в IT: пошаговый план для смены профессии

Динамическая предобработка с помощью java.lang.reflect.Proxy

Если вам нужно внедрить функционал незаметно, то java.lang.reflect.Proxy может помочь осуществить задуманное без вмешательства в основную логику.

Взглянем поближе на InvocationHandler:

Java
Скопировать код
public class МойInvocationHandler implements InvocationHandler {
    private final Object target;

    public МойInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (!method.isAnnotationPresent(НеSuperSpy.class)) {
            System.out.println("Секретный блок кода перед методом.");
        }
        // Исполнение основной логики метода
        return method.invoke(target, args);
    }
}

Создайте прокси для вашего интерфейса с помощью Proxy.newProxyInstance:

Java
Скопировать код
YourInterface proxy = (YourInterface) Proxy.newProxyInstance(
    ВашКласс.class.getClassLoader(),
    new Class<?>[]{YourInterface.class},
    new МойInvocationHandler(new ВашКласс())
);

Использование аннотации @НеSuperSpy позволяет отключить выполнение кода:

Java
Скопировать код
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface НеSuperSpy { }

Делаем код DRY

Необходимость ведения одной и той же последовательности кода отпадает – следующие подходы сделают ваш код DRY и избавят от повторения.

Помните о производительности

Такое применение рефлексии и проксирования может отрицательно сказаться на производительности, поэтому стоит применять эти подходы осмотрительно.

Визуализация

Для углубления понимания визуализируем процесс предварительного выполнения кода. Мы вновь обращаемся к аналогии с конвейером.

Markdown
Скопировать код
[💼 Методы класса 💼]

Каждый вызов метода проходит через конвейер:

Markdown
Скопировать код
Старт конвейера: 🔄 Предварительный блок кода

Мы можем отследить путешествие каждого метода через начальный этап:

Markdown
Скопировать код
🔄 → 💼 method1()
🔄 → 💼 method2()
🔄 → 💼 method3()

Это как проверка перед полетом: блок кода выполняется перед основной частью метода.

Изменяем поведение методов без дублирования

Чтобы изменить поведение метода без дублирования кода, воспользуйтесь Шаблоном стратегии или Шаблоном состояния.

Автоматизация создания кода

Если вам нужно сократить время на рутинное написание кода, обрататегь к генераторам кода и шаблонизаторам.

Полезные материалы

  1. Аспектно-ориентированное программирование с Spring – обзор АОП в Spring для управления функциональностью.
  2. Byte Buddy – Генерация кода во время выполнения для JVM – как генерировать байт-код на лету.
  3. Использование Java Reflection – отличное пособие от Oracle об использовании API рефлексии в Java.
  4. Стандартные аннотации (Java™ Tutorials) – всё о аннотациях и создании кода.
  5. Обсуждение на StackOverflow: Как использовать AOP в PHP – интересное обсуждение АОП в контексте PHP.
Свежие материалы