JavaRush /Java 博客 /Random-ZH /在 Java 中创建您自己的注释
angelina
第 5 级

在 Java 中创建您自己的注释

已在 Random-ZH 群组中发布
文章作者:Jonny Hackett 2014 年 7 月 14 日 上午 11:09 如果您使用 Java 编程并使用任何流行的框架(例如SpringHibernate),那么您已经熟悉注释的使用。当使用现有框架时,内部注释就足够了。但是如果您需要创建自己的注释怎么办?不久前,我有理由为一个需要确认多个数据库中的公共信息的项目创建自己的注释。场景 一家企业拥有多个数据库,这些数据库存储相同的信息并以不同的方式更新数据。计划将这些数据合并到一个主数据库中,以消除从不同来源获取数据所带来的问题。但在项目开始之前,有必要找出数据不同步的程度并进行必要的更改。第一步是创建一个报告,该报告将显示不同数据库中的相同数据并根据既定的对账规则确认这些值,或突出显示那些不匹配的记录。以下是该项目当时主要需求的摘录: • 比较多个数据库中的数据以查找相同的数据,例如客户名称、公司名称或目录信息。• 默认情况下,根据数据类型,该值在所有数据库中应该完全相同。• 对于某些字段,我们只想显示已找到该值,但不比较该值。• 对于其他字段,我们只想将值与找到的值进行比较,并与指定来源的数据确认数据。• 对于第三个字段,我们希望基于记录中其他字段的值进行复杂的数据比较。• 对于第四种字段类型,我们希望对数据进行格式化,例如采用货币格式$000,000.00。• 报告必须采用MS Excel 格式,每行应包含来自单独来源的值。任何其值与数据确认条件不匹配的行都应以黄色突出显示。 注释在我们阅读了需求并针对所需内容提出了一些不同的想法后,我决定使用注释来触发数据比较配置和报告过程。我们需要一个简单但灵活且可扩展的解决方案。这些注释将位于字段级别,我喜欢这样的事实:配置不会隐藏在类路径上某处的文件中。相反,我将能够看到与该字段关联的注释,因此我确切地知道它将如何处理。简单地说,注释只不过是一个标记,是提供信息的元数据,但不会直接影响代码本身的操作。如果您以前使用过 Java 编程,您应该熟悉使用注释,但您可能从来不需要创建自己的注释。为此,您需要创建一个使用 Java @interface类型的新类型,该类型将包含依次定义元数据详细信息的元素。这是一个项目示例: 1@Target(ElementType.FIELD) 2@Retention(RetentionPolicy.RUNTIME) 3public @interface ReconField { 4 5 /** 6 * Значение, которое определяет из Howого источника сравниваются данные, or будет использоваться для 7 отображения значения or для ссылки на правило. 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 * Значение, показывающее meaning 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。在我们的Field 级别的 @ReconField注释中。@Retention – 此注释将允许您指定注释何时可用。可能的值为 CLASS、RUNTIME 和 SOURCE。由于我们将在运行时处理注释,因此必须设置这些值。数据验证过程将对每个数据库运行一个查询,然后在整体数据(即特定记录类型的所有字段)中显示结果。共享数据中每个字段的注释将告诉处理器如何比较该特定字段的数据以及每个数据库中找到的值。让我们看几个示例,了解如何将这些注释用于各种数据比较配置。要确认每个数据源中的值存在且完全匹配,您只需提供将出现在报表字段中的字段 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是一个枚举,其中的数据源可用于比较。 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 * Значение, указывающее используемые параметры, прописанные обработчику правила, meaning по умолчанию - 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中,我们指定了一个类,该类将在侦察过程开始时运行数据比较。您只能指定将使用的类,以便您的处理程序将分配一个值并初始化您指定的任何类。此注释中指定的类将使用规则接口,而处理程序将使用该接口来执行规则。让我们看一下此注释的几个示例。在此示例中,我们使用的规则将检查非美国货币兑换,并在这种情况下跳过数据比较。为此,我们需要检查同一记录中的国家/地区字段。 1 @ReconField(id = STREET_CUSIP, label = "STREET CUSIP", compareSources = false) 2 @ReconCustomRule(processor = SkipNonUSExchangeComparisonRule.class) 3 private String streetCusip; 这是我们设置规则参数的示例,在本例中为容差值。比较我们的数据,比较值的偏差不能超过1000。使用参数指定容差值将允许我们对多个字段使用相同的规则,但具有不同的容差值。唯一的问题是,由于注释的性质,这些参数是静态的,不能是动态的。 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 中的注释、它们的用途以及使用它们的规则。在本文中,我想通过示例展示为什么应该使用它们以及如何从中受益。请注意,这只是一个开始。一旦决定创建注释,您将必须弄清楚如何以最有效的方式使用它们。在第 2 部分中,我将向您展示如何使用 Java 反射处理注释。— Jonny Hackett,asktheteam@keyholesoftware.com 原始文章 http://www.javacodegeeks.com/2014/07/creating-your-own-java-annotations.html
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION