JavaRush /Java блог /Архив info.javarush /Создание своих аннотации в Java
angelina
5 уровень

Создание своих аннотации в Java

Статья из группы Архив info.javarush
статья Джонни Хакета (Jonny Hackett) 14го Июля, 2014 11:09 Если вы программируете на Java и используете любую из популярных фреймворков, такие как Spring и Hibernate, тогда вы уже знакомы с использованием аннотаций. В работе с существующей фреймворк - внутренних аннотаций вполне достаточно. Но, что если вам понадобиться создать свои собственные аннотации? Не так давно у меня появилась причина создать свои собственные аннотации для проекта, в котором требовалось подтверждение общей информации из нескольких баз данных. Сценарий У бизнеса было несколько баз данных, в которых была сохранена одинаковая информация, и данные обновлялись разными способами. Было запланировано совместить данные в одну основную базу данных, чтобы устранить проблемы, связанные с получением данных из разных источников. Но до того как начать проект, следовало выяснить насколько данные были рассинхронизированы и внести необходимые изменения. Первый шагом было создание отчета, который бы отображал одинаковые данные в разных базах данных и подтвердить значения, или выделить те записи, которые не совпадали, на основе установленных правил сверки. Ниже представлены выдержка основных требований на момент проекта: • Сравнить данные в нескольких базах данных на предмет поиска одинаковых данных, таких как имя клиента, компании или информация в каталоге. • По умолчанию значение должно точно совпадать во всех базах данных, основываясь на типе данных. • Для некоторых полей мы хотели только показать, что значение найдено, но значение не сравнивалось. • Для других полей мы хотели только сравнить значение с найденным и подтвердить данные с данными из указанного источника. • Для третьих полей мы хотели сделать сложно сравнение данных, которое бы базировалось на значении других полей внутри записи. • Для четвертого типа полей мы хотели отформатировать данные, к примеру в денежный формат $000,000.00. • Отчет должен был быть быть в формате MS Excel, каждая строка должна содержать значение из отдельного источника. Любая строка, значение которой не совпадает с условиями подтверждения данных, должна быть выделена желтым. Аннотации После того, как мы прочитали требования и озвучили несколько разных идей воплощения того, что требуется, я решил использовать аннотации, которые запустят конфигурацию сравнения данных и процесс отчета. Нам требовалось просто, но гибкое и расширяемое решение. Эти аннотации будут на уровне поля и мне понравилось то, что конфигурацию не будет скрыта в файле, где-нибудь в пути класса. Вместо этого я смогу видеть аннотации ассоциированные с полем, чтобы точно знать как оно будет обработано. Проще говоря - аннотация будет ничем иным как маркером, метаданные которая будет предоставлять информацию, но не будет напрямую воздействовать на работу самого кода. Если вы уже программировали на Java, то вам должно быть знакомо использования аннотация, но возможно вам никогда не требовалось создавать свои собственные. Для этого вам нужно создать новый тип, который использует Java тип @interface, который будет содержать элементы, которые в свою очередь определяют детали метаданных. Вот пример проекта: 1@Target(ElementType.FIELD) 2@Retention(RetentionPolicy.RUNTIME) 3public @interface ReconField { 4 5 /** 6 * Значение, которое определяет из какого источника сравниваются данные, или будет использоваться для 7 отображения значения или для ссылки на правило. 8 * 9 * @return Значение, если источники должны быть сравнены, по умолчанию true. 10 */ 11 boolean compareSources() default true; 12 13 /** 14 * Значение показывает формат, который используется для отображения значения в отчете. 15 * 16 * @return Установленный формам, по умолчанию native. 17 */ 18 ReconDisplayFormat displayFormat() default ReconDisplayFormat.NATIVE; 19 20 /** 21 * Значение, показывающее значение ID используемого поля для одинаковых значений из источника до поля. 22 * 23 * @return ID поля. 24 */ 25 String id(); 26 27 /** 28 * Значение, показывающее ярлык, который будет отображается в отчете для поля. 29 * 30 * @return Значение ярлыка, по умолчанию пустая строка. 31 */ 32 String label() default ""; 33 34 /** 35 * Значение, показывающее источник, который должен быть сравнен на предмет различий. 36 * 37 * @return Список источников для сравнения. 38 */ 39 ReconSource[] sourcesToCompare() default {}; 40 } Это основная аннотация, с помощью которой запуститься процесс сравнения данных. Она содержит основные требуемые элементы, в соответствии с требованиями, для сравнения данных из различных источников данных. @ReconField должна справиться с большинством того, что нам требуется, за исключением более сложных сравнений данных, о которых мы поговорим позже. Большинство из этих элементов объяснены комментариями в коде. Не смотря на это пара основных аннотаций в нашей @ReconField должны быть объяснены отдельно. • @Target – Эта аннотация позволит вам указать те java элементы, к которой аннотация должна быть применена. Возможные типы для применения такие: ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER и TYPE. В нашей @ReconField аннотация для уровня FIELD. • @Retention – Эта аннотация позволит вам указать, когда аннотация будет доступна. Возможные значения: CLASS, RUNTIME и SOURCE. Так как мы будет обрабатывать аннотации в RUNTIME, мы должны установить эти значения. Процесс подтверждения данных будет идти в один запрос к каждой базе данных, и затем отобразит результаты в общих данных, которые представляют собой все поля для определенного типа записи. Аннотация для каждого поля в общих данных сообщит процессору как совершать сравнение данных для этого определенного поля, а так же значение, найденное в каждой базе данных. Давайте посмотрим на несколько примеров того, как эти аннотации могу быть использованы для различных конфигураций сравнения данных. Чтобы подтвердить, что значение существует и точно соответствует в каждом источнике данных, вам всего лишь надо предоставить ID поля и ярлык, который будет отображаться в поле отчета. 1 @ReconField(id = CUSTOMER_ID, label = "Customer ID") 2 private String customerId; Чтобы отобразить найденные значения из каждого источника данных, но делать сравнения данных, вам нужно указать элемент compareSources и поставить значение на false. 1 @ReconField(id = NAME, label = "NAME", compareSources = false) 2 private String name; Чтобы подтвердить, что значение найдено в определенном источник данных, но не во всех, вам нужно использовать элемент sourcesToCompare. Это отобразить все найденные значения, но сравнение любых данных в источниках данных произойдет в соответствии со списком элементов. Это для случая, если некоторые данные не сохранены во всех источниках данных. ReconSource - это enum, в котором источники данных доступны для сравнения. 1 @ReconField(id = PRIVATE_PLACEMENT_FLAG, label = "PRIVATE PLACEMENT FLAG", sourcesToCompare ={ 2 ReconSource.LEGACY, ReconSource.PACE }) private String privatePlacementFlag; Теперь, когда мы выполнили основные требования, нам нужно выполнить сравнение более сложных данных, которые специфичный для поля. Чтобы сделать это мы создадим вторую аннотацию, которая запустит обработку правил. 1 @Target(ElementType.FIELD) 2 @Retention(RetentionPolicy.RUNTIME) 3 public @interface ReconCustomRule { 4 5 /** 6 * Значение, указывающее используемые параметры, прописанные обработчику правила, значение по умолчанию - 7 отсутствие параметров. 8 * 9 * @return The String[] параметры, прописанные обработчику правила 10 */ 11 String[] params() default {}; 12 13 /** 14 * Значение, указывающее класс обработчика правила, которое используется для сравнения значений из 15 каждого источника данных. 16 * 17 * @return Класс обработчика правила 18 */ 19 Class processor() default DefaultReconRule.class; 20 } Очень похоже на предыдущую аннотацию, одна большая разница в том, что в @ReconCustomRule мы указываем класс, которые запустит сравнение данных, когда запускается процесс recon. Вы можете указать только класс, который будет использован, чтобы ваш обработчик приписал значение и инициализировал любой класс, который вы укажите. Указанный класс в данной аннотации, будет использовать интерфейс правила, который в свою очередь будет использован обработчиком для исполнения правила. Давайте посмотрим пару примеров данной аннотации. В этом примере мы используем правило, которое проверит обмен валюты не в США и в этом случае пропустит сравнение данных. Чтобы сделать это, нам надо проверить поле страны в той же записи. 1 @ReconField(id = STREET_CUSIP, label = "STREET CUSIP", compareSources = false) 2 @ReconCustomRule(processor = SkipNonUSExchangeComparisonRule.class) 3 private String streetCusip; Вот пример, в котором мы задаем параметры правила, в данном случае значение допустимого отклонения. Для сравнения наших данных, сравниваемое значение не может отклоняться более чем на 1,000. Используя параметр для указания значения отклонения позволит нам использовать то же правила для нескольких полей, с разным значением допустимого отклонения. Единственная проблема в том, что эти параметры статические и не могут быть динамическими по причине природы аннотации. 1 @ReconField(id = USD_MKT_CAP, label = "MARKET CAP USD", displayFormat = 2 ReconDisplayFormat.NUMERIC_WHOLE, sourcesToCompare = 3 { ReconSource.LEGACY, ReconSource.PACE, ReconSource.BOB_PRCM }) 4 @ReconCustomRule(processor = ToleranceAmountRule.class, params = { "10000" }) 5 private BigDecimal usdMktCap; Как вы видите внесли немного гибкости в процесс сравнения данных из различных баз данных, используя две довольно простых аннотации. Для данного конкретного случая аннотации управляют процессом сравнения данных, так, что по сути мы оцениваем аннотации, которые мы находим в общих данных и используем их, чтобы направлять обработку. Заключение Есть множество статей по аннотациями в Java, что они делают и какие есть правила их использования. В данной статье я хотела показать, на основе примеров, почему вам следует использовать их и какие выгоды от этого вы можете получить. Учтите, что это всего лишь начало. Как только вы решите создать аннотации, вам придется понять как их использовать наиболее эффективным способом. Во второй части, я покажу вам как обрабатывать аннотации, используя Java reflection. — Jonny Hackett, asktheteam@keyholesoftware.com оригинал статьи http://www.javacodegeeks.com/2014/07/creating-your-own-java-annotations.html
Комментарии (2)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Valery Уровень 23
15 января 2020
Отвратительное изложение материала, автор не потрудился даже код нормально вставить.
Роман Венчак Уровень 20
18 сентября 2019
Ничего не ясно