Лучшая практика springboot + aop, больше не боится двойного щелчка 666

Java
Лучшая практика springboot + aop, больше не боится двойного щелчка 666

Я разобрал кое-какую архитектуру Java и материалы интервью (микросервисы, кластеры, распределенное, промежуточное ПО и т.д.), а друзья, кому нужно, могут обратить внимание на официальный аккаунт [Внутренние дела программиста], и получить самостоятельно без всяких рутин

Отличный обзор:


Нытье

Комплексные работники меньше месяца сумасшедших сверхурочных. Нет времени писать немного медленнее, а проект не все в проекте, и все еще есть некоторые значимые и практические технологические точки, поэтому сортируя поделиться его для все., Больше, чем те, кто участвует в высококачественных технологиях, я все еще кодекс, который все еще движется вперед.

有没有遇到过这种情况:由于网速等原因,网页响应很慢,提交一次表单后发现服务久久没响应,然后你就疯狂点击提交按钮(12306就经常被这样怒怼),如果做过防重复提交还好,否则那是什么级别的灾难就不好说了。 . .

В основном используется сегодня自定义注解、 AOP、· GuavaКэш в пакете используется для создания локальной блокировки для достижения эффекта антидубликатной отправки.Общая реализация относительно проста, нет особых сложностей, а код относительно небольшой.Поскольку это кеш на основе памяти ,Следовательно, эта реализация не относится к распределенным сервисам.. Он предназначен для того, чтобы познакомить вас с программой, которая реализует анти повторное представление. Если есть что-то не так, все нежные, в конце концов, у людей все еще есть 20-летний ребенок.

在这里插入图片描述

Что такое Гуава?

guavaЧто такое сумка? Друзья, которые занимались Java, должны кое-что знать об этом, этоgoogle"не нравится"JAVAВстроенная классная библиотека не проста в использовании, а набор инструментов, разработанных нами, сделал хорошее расширение инструментов JDK. Например: одновременно [Concurrency], кэш [Caches], функциональный стиль [Functional idioms], обработка строк [Strings]Ждать.

Одним словомguavaСумка очень проста в использовании.Давайте узнаем о ней подробнее.Если у нас не получается сделать колеса,стараемся их не делать,потому что колеса,которые делаем сами,могут быть не круглыми. Без лишних слов давайте взглянем на конкретную реализацию.

код вверх

1. Представьте зависимости пакета Guava

Первый шаг во введенииGuavaПакет зависимостей не о чем не говорит

<dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>21.0</version>
</dependency>
2. Пользовательские аннотации

Сервер реализует для предотвращения повторных отправок, обычно используяAOPСпособ настройки аннотации, воздействующий наcontrollerспособ входа. пользовательскийLocalLockАннотации используются в методах, которые должны предотвращать дублирование отправки.

/**
 * 锁的注解
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface LocalLock {

    /**
     * @author fly
     */
    String key() default "";
}

После хорошей аннотации определяется, вам нужно сделать раздел интернации AOP из конкретной реализации, вinterceptor()используемый методAround(расширение окружающей среды), так что все группыLocalLockВсе аннотации будут обрабатываться по аспектам;

    @Around("execution(public * *(..)) && @annotation(com.chengxy.annotation.LocalLock)")

Поскольку это кеш, следующие атрибуты должны иметь срок действия.expireAfterWriteУстановите время истечения кэша,maximumSizeУстановка количества кеша.

Запрос, существует ли ключ в памяти, определяется, будет ли она подана снова, иRedisизsetNXМетод сравнения.

Здесь мы устанавливаем тот же метод, запросы с одинаковыми параметрами за 5 секунд разрешены только для выполнения.

Так как же это отметить?

@Aspect
@Configuration
public class LockMethodInterceptor {

    private static final Cache<String, Object> CACHES = CacheBuilder.newBuilder()
            // 最大缓存 100 个
            .maximumSize(1000)
            // 设置写缓存后 5 秒钟过期
            .expireAfterWrite(5, TimeUnit.SECONDS)
            .build();

    @Around("execution(public * *(..)) && @annotation(com.chengxy.annotation.LocalLock)")
    public Object interceptor(ProceedingJoinPoint pjp) {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        LocalLock localLock = method.getAnnotation(LocalLock.class);
        String key = getKey(localLock.key(), pjp.getArgs());
        if (!StringUtils.isEmpty(key)) {
            if (CACHES.getIfPresent(key) != null) {
                throw new RuntimeException("请勿重复请求");
            }
            // 如果是第一次请求,就将 key 当前对象压入缓存中
            CACHES.put(key, key);
        }
        try {
            return pjp.proceed();
        } catch (Throwable throwable) {
            throw new RuntimeException("服务器异常");
        } finally {
            // TODO 为了演示效果,这里就不调用 CACHES.invalidate(key); 代码了
        }
    }

    /**
     * key 的生成策略,如果想灵活可以写成接口与实现类的方式(TODO 后续讲解)
     *
     * @param keyExpress 表达式
     * @param args       参数
     * @return 生成的key
     */
    private String getKey(String keyExpress, Object[] args) {
        for (int i = 0; i < args.length; i++) {
            keyExpress = keyExpress.replace("arg[" + i + "]", args[i].toString());
        }
        return keyExpress;
    }
}
3. Реализация уровня управления

Мы добавляем аннотацию к методу слоя управления,key = "city:arg[0]собственное определение ключа,arg[0]Это правило сопоставления означает, что первый параметр заменяется. тогда осознайтеcity:tokenПовторная подача не допускается в течение определенного периода времени

@RestController
@RequestMapping("/city")
public class BookController {

    @LocalLock(key = "city:arg[0]")
    @GetMapping
    public String query(@RequestParam String token) {
        return "ok- " + token;
    }
}
4. Тест

Далее давайте проверим, ожидаемый результат: только первый сабмит будет возвращен нормально в течение 5 секунд, а остальные будут отображаться“请勿重复提交”, чтобы увидеть, является ли результат выполнения тем, что мы ожидали, здесь мы используемpostmanконтрольная работа.

Первый запрос отвечает нормально:

在这里插入图片描述

Сразу после второго запроса возвращается результат "resubmitted", очевидно, нам это удалось

在这里插入图片描述


Так много, что нужно сказать сегодня, если эта статья была вам полезна, я надеюсь получить от вас лайк 👍

Ваше одобрение является движущей силой для моего письма!


Небольшие преимущества:

Сотни различных технических электронных книг пересылаются друг другу, тсс~,бесплатноДайте мелких партнеров. Нет публичного ответа [666] Самовывоз

Я разобрал кое-какую архитектуру Java и материалы интервью, а нуждающиеся друзья могут обратить внимание на паблик-аккаунт [Внутри программатора