Можно ли применять Spring AOP к определенным полям при создании DTO?

Я хочу скрыть личную информацию при создании Java DTO. Я создал аннотацию PersonalInfo и добавил ее в поле, которое хочу замаскировать. Однако я не знаю, как написать совет в классе PersonalInfoAspect.

@Getter
@Builder
public class User {

    private String id;

    @PersonalInfo
    private String name; 
}
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PersonalInfo {
}
@Aspect
@Component
public class PersonalInfoAspect {
    
    // ...
}

При создании DTO следует ли вызывать AOP при вызове конструктора для изменения значения поля?

При создании пользовательского DTO, как показано ниже, я хочу, чтобы он был замаскирован и сохранен с использованием Spring AOP.

При создании DTO я хочу перехватить конструктор и сгенерировать его как замаскированные данные. Наконец, предоставляя его как API с использованием dto, я хочу предоставить его как замаскированные данные, даже если в БД есть немаскированные данные.

Добро пожаловать в СО. Пожалуйста, отредактируйте свой вопрос, чтобы уточнить, чего вы хотите достичь, потому что ваша формулировка неясна и двусмысленна. Ваш код nsippet в нижней части вопроса тоже не помогает. «При создании DTO» звучит так, будто вы хотите перехватывать вызовы конструктора. Затем вы говорите, что «хотите, чтобы он был замаскирован и сохранен с использованием Spring AOP». Я не могу представить, что вы хотите сохранить замаскированное значение вместо исходного. Возможно, вы хотите зарегистрировать замаскированное значение, но когда именно? Как я уже сказал, вопрос совершенно не ясен.

kriegaex 19.01.2023 12:14

Спасибо. При создании DTO я хочу перехватить конструктор и сгенерировать его как замаскированные данные. Наконец, предоставляя его как API с использованием dto, я хочу предоставить его как замаскированные данные, даже если в БД есть немаскированные данные.

kaven 20.01.2023 08:45

Теперь я понимаю это немного лучше, но все же не на 100%, потому что ваша формулировка все еще неясна: что означает «при предоставлении его как API с использованием dto»? Ваш код также не сообщает о ваших намерениях. Я предлагаю вам создать MCVE на GitHub, т.е. минимальный проект, изолирующий и воспроизводящий вашу проблему. Затем напишите небольшой, неудачный модульный тест (или основной метод с утверждениями), проверяющий поведение, которое вы ожидаете для обоих случаев, которые вы описали. тогда я легко смогу вам помочь. Но я не люблю гадать.

kriegaex 20.01.2023 14:10

Что я уже могу вам сказать, так это то, что если вы хотите перехватить доступ к полям для чтения/записи или конструкторы, вы все равно не можете использовать Spring AOP на основе прокси. Это сложный случай, требующий родного AspectJ. Вы можете использовать AspectJ с Spring или без него, и вы не ограничены перехватом вызовов методов компонентов Spring. Это работает для любого кода. Если вы хотите избежать нативного AspectJ, вам придется создать компонент Spring с фабричными методами для вашего DTO, который вы можете перехватить. Если сам DTO является @Component, вы также можете перехватить его методы установки/получения.

kriegaex 20.01.2023 14:19
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
63
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете написать аспект для геттеров. Помните, что Lombok @Getter генерирует простые старые методы получения для полей, которые можно перехватить. Вам, вероятно, придется пометить свои DTO, которые должны быть затронуты, например, некоторой аннотацией (а также поля, чтобы показать, какие поля должны быть запутаны)

К вашему сведению, то, что вы называете «Spring AOP», будет работать только с управляемыми bean-компонентами (@Component), но использование AOP в целом будет работать. В качестве точки пересечения вы можете использовать операторы return, которые возвращают ваши DTO, чтобы они были запутаны прямо перед передачей управления обратно в Spring.

Вам понадобится совет @Around по аннотации, но только для указателя точки выполнения, например -

@Around("@annotation(your.package.PersonalInfo) && execution(* *.*(..))")
public Object maskValue(final ProceedingJoinPoint jp) {
    Object obj = jp.proceed();
    if (obj == null && !jp.getSignature().getName().contains("get")) {
        return jp.proceed();
    }
    String value = String.valueOf(obj);
    obj = someFunction(value); // method call for your logic
    return obj;
}

Выполнение (...) будет сканировать все пакеты для указанной аннотации. Его также можно настроить на сканирование определенного пакета, чтобы ограничить сканирование.

Другие вопросы по теме