«1. Обзор

В этом руководстве мы продолжаем текущую серию «Регистрация в Spring Security», чтобы настроить запланированную задачу для очистки VerificationTokens с истекшим сроком действия. В процессе регистрации VerificationToken сохраняется. В этой статье мы покажем, как удалить эти объекты.

2. Удаление токена с истекшим сроком действия

Вспомним из предыдущей статьи этой серии, что токен проверки имеет член expiryDate, представляющий отметку времени истечения срока действия токена:

@Entity
public class VerificationToken {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String token;

    @OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)
    @JoinColumn(nullable = false, name = "user_id", 
      foreignKey = @ForeignKey(name="FK_VERIFY_USER"))
    private User user;

    private Date expiryDate;
    ...
}

Мы будем использовать это свойство expiryDate для создания запроса с Spring Data.

Если вам нужна дополнительная информация о Spring Data JPA, ознакомьтесь с этой статьей.

2.1. Операция удаления

Чтобы облегчить удаление токена, мы добавим в наш VerificationTokenRepository новый метод для удаления просроченных токенов:

public interface VerificationTokenRepository
  extends JpaRepository<VerificationToken, Long> {

    void deleteByExpiryDateLessThan(Date now);
}

Использование ключевого слова запроса LessThan указывает механизму создания запросов Spring Data, что мы только заинтересованы в токенах, у которых свойство expiryDate меньше указанного времени.

Обратите внимание, что, поскольку VerificationToken имеет ассоциацию @OneToOne с пользователем, отмеченным FetchType.EAGER, выбор также выдается для заполнения сущности пользователя, даже если сигнатура deleteByExpiryDateLessThan имеет возвращаемый тип void:

select 
    *
from 
    VerificationToken verification 
where 
    verification.expiryDate < ?

select 
    * 
from
    user_account user 
where
    user.id=?

delete from 
    VerificationToken
where
    id=?

2.2. Удаление с помощью JPQL

В качестве альтернативы мы можем создать запрос JPQL, если у нас нет необходимости загружать объекты в контекст сохранения:

public interface VerificationTokenRepository
  extends JpaRepository<VerificationToken, Long> {

    @Modifying
    @Query("delete from VerificationToken t where t.expiryDate <= ?1")
    void deleteAllExpiredSince(Date now);
}

И Hibernate не будет загружать объекты в контекст сохранения: ~ ~~

delete from
    VerificationToken
where
    expiryDate <= ?

3. Планирование задачи очистки токена

Теперь у нас есть запрос, который мы хотим периодически выполнять; Мы будем использовать поддержку планирования в Spring и создадим метод для запуска нашей логики удаления.

Если вам нужна дополнительная информация о структуре Spring Job Scheduling, ознакомьтесь с этой статьей.

3.1. Включить планирование

Чтобы включить планирование задач, мы создаем новый класс конфигурации SpringTaskConfig с аннотацией @EnableScheduling:

@Configuration
@EnableScheduling
public class SpringTaskConfig {
    //
}

3.2. Purge Token Task

На сервисном уровне мы вызываем наш репозиторий с текущим временем.

Затем мы аннотируем метод @Scheduled, чтобы указать, что Spring должен выполнять его периодически:

@Service
@Transactional
public class TokensPurgeTask {

    @Autowired
    private VerificationTokenRepository tokenRepository;

    @Scheduled(cron = "${purge.cron.expression}")
    public void purgeExpired() {
        Date now = Date.from(Instant.now());
        tokenRepository.deleteAllExpiredSince(now);
    }
}

3.3. Расписание

Мы использовали свойство для хранения значений настроек crontab, чтобы избежать перекомпиляции при изменении. В application.properties присваиваем значение:

#    5am every day
purge.cron.expression=0 0 5 * * ?

4. Заключение

В этой статье мы решили удаление VerificationTokens с помощью Spring Data JPA.

Мы продемонстрировали создание запроса с использованием выражения свойства для поиска всех токенов, срок действия которых меньше указанного времени. И мы создали задачу для вызова этой чистой логики во время выполнения — и зарегистрировали ее в структуре Spring Job Scheduling для периодического выполнения.

Реализацию этого руководства по регистрации с помощью Spring Security можно найти в проекте github — это проект на основе Eclipse, поэтому его должно быть легко импортировать и запускать как есть.