В ходе разработки приложения будут существовать разное время, что будет необходимо, мы реализуем какой-то кэш. Есть, чтобы меньше допуска к какой-то внешней службе, как базы данных или веб-службы, или, чтобы избежать создания ненужных объектов, высказываний, как “дорого”. Типичные примеры такого рода объект EntityManagerFactory, Источники, etc…
Как правило, мы должны изменить исходный код, чтобы использовать кэш-памяти в какой-то момент нашей системе. Может быть, что это всего лишь простой if
или изменения сложная, мы не будем бежать “пакостить” наш код с каким-то проверки или лечения.
В приведенном ниже примере у нас есть процедура до и после внедрения кэш-памяти с помощью HashMap:
Перед кэша
После того, как кэш
Может показаться, что простое изменение, но, в зависимости от количества методов, которые должны быть вьющиеся, как методы, организованы или, как значения будут сохранены в кэш-памяти, может стать сложной. В предыдущем примере, идентификатор для доступа к предупреждениям, это собственный код пользователя, для которого уведомление было направлено, но возможны и другие ситуации, в которых нам нужно будет идентифицировать пользователя и даты, или только по дате. В балансе времени все может измениться.
Para evitar on incluir este tipo de regla de interesse transversal no nosso código, vamos utilizer 2 funcionalidades bastante utilizadas no mundo java: os прокси динамические и в качестве аннотаций.
Прокси-сервер Dinâmico
Это класс, который может реализовать множество интерфейсов, определенных во время выполнения, а каждый вызов, сделанный из этих методов этих интерфейсов, диспетчер будет называться и будет отвечать за определение поведения метода. То есть, мы будем управления следующий метод для вызова действий, прежде чем произойдет.
Прокси-серверы используются в мире рамки инъекции зависимостей. Ибо, как не мы создаем наши объекты явно с помощью команды new
, это дает свободу, чтобы они, внутренне, создавать прокси-объекты, добавляя функции, они, что в первый момент может показаться, что магия, как открыть e закрыть транзакцию в бд во время выполнения метода или вызвать другой фрагмент кода, который “перехватывает” наш объект.
На этом примеры не используем прокси-механизм родной от jdk, но да, предоставленного библиотекой cglib . Благодаря этому lib не мы застрянем использование динамических прокси, только в интерфейсах, и мы можем использовать их в конкретных классов.
Аннотации
В аннотации аннотации, с другой стороны, не были сделаны, чтобы изменить поведение объекта во время выполнения, но установить информацию(метаданные) в отношении определенного объекта, которые могут быть получены во время выполнения или компиляции. Мы можем видеть использование аннотаций всегда, что мы реализовали в метод интерфейса или необходимо переопределить метод, то суперкласса.
В случае, если @Override
, мы добавленные информация, что следующий метод работает на индекс, который не принадлежит изначально этот класс. Технически это не изменяет поведение приложения, но с помощью прокси-сервера можно проверить, если метод, класс, параметр или атрибут содержит примечания, и с этого добавить новое поведение в соответствии с проинформированы получены.
Реализован наш кэш
Для начала, давайте определим наши аннотации и какую информацию они помогут нам пройти.
Через заметки Cacheable
сообщим вам, какой метод мы хотели бы cachear и какой код его в кэш.
После определения, который определяет метод, как cacheável, мы с api ответственность за предоставление данных, вьющиеся
Класс CacheValue
будет иметь роль представляют ценность фигурные в наш api, а также содержать дополнительную информацию, такую как дата создания ценности.
Чтобы просмотреть или изменить эти значения выполним реализацию интерфейса CacheManager
Может быть, интерфейс приобретали определенную свободу, чтобы установить механизм/engine хранения данных. В этом примере мы будем сохранять данные в Map. Если мы хотим что-то более сложное, в будущем просто заменить реализацию, чтобы использовать что-то более “мощный”, как Овчарня или даже СУБД.
Реализации CacheManager
, которые мы используем в этом примере:
Теперь давайте перейдем к прокси-сервера…
Как было сказано ранее, мы будем использовать cglib для создания proxy’s конкретных классов. Чтобы включить эту зависимость в проект maven, просто добавьте зависимость ниже нет pom.xml
cglib cglib 3.2.4
В библиотеке Com essa нет пути к классу, реализован интерфейс net.sf.cglib.proxy. MethodInterceptor
, которые содержат метод перехват(Объект o, Метод method, Объект[] os, методproxy mp)
. Он, как говорит его название, будет перехватывать любой метод чей вызов был сделан за экземпляр прокси-сервера. Через класс Method
у нас есть бесплатный метод, который работает. Мы используем эту информацию, чтобы знать, какие будут вьющиеся или нет. Класс CacheProxy
ниже показывает вся логика:
Следующий фрагмент кода демонстрирует метод, который мы будем использовать для создания прокси-серверов. В нем мы видим, как мы определяем класс, который будет ‘proxiada” и как мы связываем в MethodInteceptor.
С помощью нашего кэша
Давайте создадим класс, вымышленный отвечает за вывод сообщений, доступных для каждого пользователя и установить его метод с аннотацией @Cacheable
Значения будут сохранены в структуре Map (Ключ => Значение) следующим образом:
CHAVE VALOR ------------ --- |"USER_MESSAGE"| 1 | => [MENSAGEM_1, MENSAGEM_2] ------------ --- -------------- --- |"USER_MESSAGE"| 2 | => [] -------------- ---
O cacheName
определена в аннотации, в сочетании со значениями параметров, будут использованы в качестве идентификаторов для сохранения возвращение метод кэширования. Таким образом, каждый вызов метода, используя различные значения в параметре “запись” фигурные.
Некоторые тесты были сделаны для проверки функционирования нашего механизма кэширования.
set 05, 2021 6:26:22 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Executando método cacheavel: getMessagesOfUser set 05, 2021 6:26:22 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Consultando valor no cache... set 05, 2021 6:26:22 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Não foi encontrado nenhum valor no cache. Executando método original... set 05, 2021 6:26:22 PM br.com.simplecache.service.MessageService getMessagesOfUser INFORMAÇÕES: Acessando messagens do usuário... set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Salvando retorno no cache... set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Executando método cacheavel: getMessagesOfUser set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Consultando valor no cache... set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Retornando valor cacheado É a mesma lista: true set 05, 2021 6:26:23 PM br.com.simplecache.core.SimpleCacheManager removeAll INFORMAÇÕES: Limpando todo o cache set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Executando método cacheavel: getMessagesOfUser set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Consultando valor no cache... set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Não foi encontrado nenhum valor no cache. Executando método original... set 05, 2021 6:26:23 PM br.com.simplecache.service.MessageService getMessagesOfUser INFORMAÇÕES: Acessando messagens do usuário... set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept INFORMAÇÕES: Salvando retorno no cache... É a mesma lista: false
В этом посте я решил показать один из способов реализации кэша, немного более сложные, но не с того, чтобы использовать контейнер CDI, сервер приложений, или перейти на Spring, который уже существующих систем не у нас столько свободы для реализации такого решения, и это стало предложение менее инвазивной.
Репозиторий com os fontes: https://github.com/josevjunior/simple-cache-manager
Характеристика
- Характеристика
- https://refactoring.guru/pt-br/design-patterns/proxy/java/example
- https://refactoring.guru/pt-br/design-patterns/proxy/java/example
Оригинал: “https://dev.to/josevjunior/cache-de-dados-utilizando-proxy-dinamico-e-annotations-3k9g”