{"id":27861,"date":"2014-07-17T16:00:01","date_gmt":"2014-07-17T13:00:01","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=27861"},"modified":"2014-07-17T07:10:25","modified_gmt":"2014-07-17T04:10:25","slug":"creating-your-own-java-annotations","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html","title":{"rendered":"Creating Your Own Java Annotations"},"content":{"rendered":"<p>If you\u2019ve been programming in Java and using any one of the popular frameworks\u00a0like\u00a0Spring and Hibernate, you should be very familiar with using annotations. When working with an existing framework, its annotations typically suffice. But, have you ever found a need to create your own annotations?<\/p>\n<p>Not too long ago, I found a reason to create my\u00a0own annotations for a project that involved verifying common data stored in multiple databases.<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<\/p>\n<h2>The Scenario<\/h2>\n<p>The business had multiple databases that were storing the same information and had various means of keeping the data up to date. The business had planned a project to consolidate the data into a master database to alleviate some of the issues involved with having multiple sources of data.<\/p>\n<p>Before the project could begin however, the business needed to know how far out of sync the data was and make any necessary corrections to get in back in sync. The first step required creating a report that showed common data that belonged in multiple databases and validated the values, highlighting any records that didn\u2019t match according to the reconciliation rules defined. Here\u2019s a short summary of the requirements at the time:<\/p>\n<ul>\n<li>Compare the data between multiple databases for a common piece of data, such as a customer, company, or catalog information.<\/li>\n<li>By default the value found should match exactly across all of the databases based upon the type of value.<\/li>\n<li>For certain fields we only want to display the value found and not perform any data comparison.<\/li>\n<li>For certain fields we only want to compare the value found and perform data verification on the specific data sources specified.<\/li>\n<li>For certain fields we may want to do some complicated data comparisons that may be based on the value of other fields within the record.<\/li>\n<li>For certain fields we may want to format the data in a specific format, such as $000,000.00 for monetary amounts.<\/li>\n<li>The report should be in MS Excel format, each row containing the field value from each source. Any row that doesn\u2019t match according to the data verification rules should be highlighted in yellow.<\/li>\n<\/ul>\n<h2>Annotations<\/h2>\n<p>After going over the requirements and knocking around a few ideas, I decided to use annotations to drive the configuration for the data comparison and reporting process. We needed something that was somewhat simple, yet highly flexible and extensible. These annotations will be at the field level and I like the fact that the configuration won\u2019t be hidden away in a file somewhere on the classpath. Instead you\u2019ll be able to look at the annotation associated with a field to know exactly how it will be processed.<\/p>\n<p>In the simplest terms, an annotation is nothing more than a marker, metadata that provides information but has no direct effect on the operation of the code itself. If you\u2019ve been doing Java programming for a while now you should be pretty familiar with their use, but maybe you\u2019ve never had a need to create your own. To do that you\u2019ll need to create a new type that uses the Java type <strong>@interface<\/strong> that will contain the elements that specify the details of the metadata.<\/p>\n<p>Here\u2019s an example from the project:<\/p>\n<pre class=\" brush:java;wrap-lines:false\">@Target(ElementType.FIELD)\r\n@Retention(RetentionPolicy.RUNTIME)\r\npublic @interface ReconField {\r\n\r\n    \/**\r\n     * Value indicates whether or not the values from the specified sources should be compared or will be used to display values or reference within a rule.\r\n     *\r\n     * @return The value if sources should be compared, defaults to true.\r\n     *\/\r\n    boolean compareSources() default true;\r\n\r\n    \/**\r\n     * Value indicates the format that should be used to display the value in the report.\r\n     *\r\n     * @return The format specified, defaulting to native.\r\n     *\/\r\n    ReconDisplayFormat displayFormat() default ReconDisplayFormat.NATIVE;\r\n\r\n    \/**\r\n     * Value indicates the ID value of the field used for matching source values up to the field.\r\n     *\r\n     * @return The ID of the field.\r\n     *\/\r\n    String id();\r\n\r\n    \/**\r\n     * Value indicates the label that should be displayed in the report for the field.\r\n     *\r\n     * @return The label value specified, defaults to an empty string.\r\n     *\/\r\n    String label() default \"\";\r\n\r\n    \/**\r\n     * Value that indicates the sources that should be compared for differences.\r\n     *\r\n     * @return The list of sources for comparison.\r\n     *\/\r\n    ReconSource[] sourcesToCompare() default {};\r\n\r\n}<\/pre>\n<p>This is the main annotation that will drive how the data comparison process will work. It contains the basic elements required to fulfill most of the requirements for comparing the data amongst the different data sources. The <strong>@ReconField<\/strong> should handle most of what we need except for the requirement of more complex data comparison, which we\u2019ll go over a little bit later. Most of these elements are explained by the comments associated with each one in the code listing, however there are a couple of key annotations on our @ReconField that need to be pointed out.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<ul>\n<li><strong>@Target<\/strong> \u2013 This annotation allows you to specify which java elements your annotation should apply to. The possible target types are ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER and TYPE. In our @ReconField annotation it is specific to the FIELD level.<\/li>\n<li><strong>@Retention<\/strong> \u2013 This allows you to specify when the annotation will be available. The possible values are CLASS, RUNTIME and SOURCE. Since we\u2019ll be processing this annotation at RUNTIME, that\u2019s what this needs to be set to.<\/li>\n<\/ul>\n<p>This data verification process will run one query for each database and then map the results to a common data bean that represents all of the fields for that particular type of business record. The annotations on each field of this mapped data bean tell the processor how to perform the data comparison for that particular field and its value found on each database. So let\u2019s look at a few examples of how these annotations would be used for various data comparison configurations.<\/p>\n<p>To verify that the value exists and matches exactly in each data source, you would only need to provide the field ID and the label that should be displayed for the field on the report.<\/p>\n<pre class=\" brush:bash\">@ReconField(id = CUSTOMER_ID, label = \"Customer ID\")\r\nprivate String customerId;<\/pre>\n<p>To display the values found in each data source, but not do any data comparisons, you would need to specify the element <strong>compareSources<\/strong> and set its value to false.<\/p>\n<pre class=\" brush:bash\">@ReconField(id = NAME, label = \"NAME\", compareSources = false)\r\nprivate String name;<\/pre>\n<p>To verify the values found in specific data sources but not all of them, you would use the element <strong>sourcesToCompare<\/strong>. Using this would display all of the values found, but only perform any data comparisons on the data sources listed in the element. The handles the case in which some data is not stored in every data source. <strong>ReconSource<\/strong> is an enum that contains the data sources available for comparison.<\/p>\n<pre class=\" brush:java;wrap-lines:false\">@ReconField(id = PRIVATE_PLACEMENT_FLAG, label = \"PRIVATE PLACEMENT FLAG\", sourcesToCompare ={ ReconSource.LEGACY, ReconSource.PACE })\r\nprivate String privatePlacementFlag;<\/pre>\n<p>Now that we\u2019ve covered our basic requirements, we need to address the ability to run complex data comparisons that are specific to the field in question. To do that, we\u2019ll create a second annotation that will drive the processing of custom rules.<\/p>\n<pre class=\" brush:java;wrap-lines:false\">@Target(ElementType.FIELD)\r\n@Retention(RetentionPolicy.RUNTIME)\r\npublic @interface ReconCustomRule {\r\n\r\n\/**\r\n* Value indicates the parameters used to instantiate a custom rule processor, the default value is no parameters.\r\n*\r\n* @return The String[] of parameters to instantiate a custom rule processor.\r\n*\/\r\nString[] params() default {};\r\n\r\n\/**\r\n* Value indicates the class of the custom rule processor to be used in comparing the values from each source.\r\n*\r\n* @return The class of the custom rule processor.\r\n*\/\r\nClass&lt;?&gt; processor() default DefaultReconRule.class;\r\n\r\n}<\/pre>\n<p>Very similar to the previous annotation, the biggest difference in the <strong>@ReconCustomRule<\/strong> annotation is that we are specifying a class that will execute the data comparison when the recon process executes. You can only define the class that will be used, so your processor will have to instantiate and initialize any class that you specify. The class that is specified in this annotation will need to implement a custom rule interface, which will be used by the rule processor to execute the rule.<\/p>\n<p>Now let\u2019s take a look at a couple of examples of this annotation.<\/p>\n<p>In this example, we\u2019re using a custom rule that will check to see if the stock exchange is not the United States and skip the data comparison if that\u2019s the case. To do this, the rule will need to check the exchange country field on the same record.<\/p>\n<pre class=\" brush:bash\">@ReconField(id = STREET_CUSIP, label = \"STREET CUSIP\", compareSources = false)\r\n@ReconCustomRule(processor = SkipNonUSExchangeComparisonRule.class)\r\nprivate String streetCusip;<\/pre>\n<p>Here\u2019s an example where we are specifying a parameter for the custom rule, in this case it\u2019s a tolerance amount. For this specific data comparison, the values being compared cannot be off by more than 1,000. By using a parameter to specify the tolerance amount, this allows us to use the same custom rule on multiple fields with different tolerance amounts. The only drawback is that these parameters are static and can\u2019t be dynamic due to the nature of annotations.<\/p>\n<pre class=\" brush:java;wrap-lines:false\">@ReconField(id = USD_MKT_CAP, label = \"MARKET CAP USD\", displayFormat = ReconDisplayFormat.NUMERIC_WHOLE, sourcesToCompare =\r\n{ ReconSource.LEGACY, ReconSource.PACE, ReconSource.BOB_PRCM })\r\n@ReconCustomRule(processor = ToleranceAmountRule.class, params =\t{ \"10000\" })\r\nprivate BigDecimal usdMktCap;<\/pre>\n<p>As you can see, we\u2019ve designed quite of bit of flexibility into a data verification report for multiple databases by just using a couple of fairly simple annotations. For this particular case, the annotations are driving the data comparison processing so we\u2019re actually evaluating the annotations that we find on the mapped data bean and using those to direct the processing.<\/p>\n<h2>Conclusion<\/h2>\n<p>There are numerous articles out there already about Java annotations, what they do, and the rules for using them. I wanted this article to focus more on an example of why you might want to consider using them and see the benefit directly.<\/p>\n<p>Keep in mind that this is only the starting point, once you have decided on creating annotations you\u2019ll still need to figure out how to process them to really take full advantage of them. In part two, I\u2019ll show you how to process these annotations using Java reflection. Until then, here are a couple of good resources to learn more about Java annotations:<\/p>\n<ul>\n<li>The Java Annotation Tutorial &#8211;\u00a0<a href=\"http:\/\/docs.oracle.com\/javase\/tutorial\/java\/annotations\/\" target=\"_blank\">http:\/\/docs.oracle.com\/javase\/tutorial\/java\/annotations\/<\/a><\/li>\n<li>Java Annotations &#8211;\u00a0<a href=\"http:\/\/tutorials.jenkov.com\/java\/annotations.html\" target=\"_blank\">http:\/\/tutorials.jenkov.com\/java\/annotations.html<\/a><\/li>\n<li>How Annotations Work &#8211;\u00a0<a href=\"http:\/\/java.dzone.com\/articles\/how-annotations-work-java\" target=\"_blank\">http:\/\/java.dzone.com\/articles\/how-annotations-work-java<\/a><\/li>\n<\/ul>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"http:\/\/keyholesoftware.com\/2014\/07\/14\/creating-java-annotations\/\">Creating Your Own Java Annotations<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Jonny Hackett at the <a href=\"http:\/\/keyholesoftware.com\/\">Keyhole Software<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019ve been programming in Java and using any one of the popular frameworks\u00a0like\u00a0Spring and Hibernate, you should be very familiar with using annotations. When working with an existing framework, its annotations typically suffice. But, have you ever found a need to create your own annotations? Not too long ago, I found a reason to &hellip;<\/p>\n","protected":false},"author":471,"featured_media":148,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[343],"class_list":["post-27861","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-core-java","tag-annotations"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Creating Your Own Java Annotations - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"If you\u2019ve been programming in Java and using any one of the popular frameworks\u00a0like\u00a0Spring and Hibernate, you should be very familiar with using\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Creating Your Own Java Annotations - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"If you\u2019ve been programming in Java and using any one of the popular frameworks\u00a0like\u00a0Spring and Hibernate, you should be very familiar with using\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:author\" content=\"http:\/\/facebook.com\/keyholesoftware\" \/>\n<meta property=\"article:published_time\" content=\"2014-07-17T13:00:01+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Keyhole Software\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/keyholesoftware\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Keyhole Software\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html\"},\"author\":{\"name\":\"Keyhole Software\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/621b02d9eb189f8d1aec83b2bcfa14d6\"},\"headline\":\"Creating Your Own Java Annotations\",\"datePublished\":\"2014-07-17T13:00:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html\"},\"wordCount\":1438,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"keywords\":[\"Annotations\"],\"articleSection\":[\"Core Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html\",\"name\":\"Creating Your Own Java Annotations - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"datePublished\":\"2014-07-17T13:00:01+00:00\",\"description\":\"If you\u2019ve been programming in Java and using any one of the popular frameworks\u00a0like\u00a0Spring and Hibernate, you should be very familiar with using\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2014\\\/07\\\/creating-your-own-java-annotations.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Core Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/core-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Creating Your Own Java Annotations\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/621b02d9eb189f8d1aec83b2bcfa14d6\",\"name\":\"Keyhole Software\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/68be341bef51b95ced09befd6a7e0ca930461d95f3a64285e03e7925b8f5de47?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/68be341bef51b95ced09befd6a7e0ca930461d95f3a64285e03e7925b8f5de47?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/68be341bef51b95ced09befd6a7e0ca930461d95f3a64285e03e7925b8f5de47?s=96&d=mm&r=g\",\"caption\":\"Keyhole Software\"},\"description\":\"Keyhole is a midwest-based consulting firm with a tight-knit technical team. We work primarily with Java, JavaScript and .NET technologies, specializing in application development. We love the challenge that comes in consulting and blog often regarding some of the technical situations and technologies we face.\",\"sameAs\":[\"http:\\\/\\\/keyholesoftware.com\\\/\",\"http:\\\/\\\/facebook.com\\\/keyholesoftware\",\"http:\\\/\\\/linkedin.com\\\/company\\\/keyhole-software\",\"https:\\\/\\\/x.com\\\/http:\\\/\\\/twitter.com\\\/keyholesoftware\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/keyhole-software\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Creating Your Own Java Annotations - Java Code Geeks","description":"If you\u2019ve been programming in Java and using any one of the popular frameworks\u00a0like\u00a0Spring and Hibernate, you should be very familiar with using","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html","og_locale":"en_US","og_type":"article","og_title":"Creating Your Own Java Annotations - Java Code Geeks","og_description":"If you\u2019ve been programming in Java and using any one of the popular frameworks\u00a0like\u00a0Spring and Hibernate, you should be very familiar with using","og_url":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_author":"http:\/\/facebook.com\/keyholesoftware","article_published_time":"2014-07-17T13:00:01+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","type":"image\/jpeg"}],"author":"Keyhole Software","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/keyholesoftware","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Keyhole Software","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html"},"author":{"name":"Keyhole Software","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/621b02d9eb189f8d1aec83b2bcfa14d6"},"headline":"Creating Your Own Java Annotations","datePublished":"2014-07-17T13:00:01+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html"},"wordCount":1438,"commentCount":1,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","keywords":["Annotations"],"articleSection":["Core Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html","url":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html","name":"Creating Your Own Java Annotations - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","datePublished":"2014-07-17T13:00:01+00:00","description":"If you\u2019ve been programming in Java and using any one of the popular frameworks\u00a0like\u00a0Spring and Hibernate, you should be very familiar with using","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2014\/07\/creating-your-own-java-annotations.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Core Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/core-java"},{"@type":"ListItem","position":4,"name":"Creating Your Own Java Annotations"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/621b02d9eb189f8d1aec83b2bcfa14d6","name":"Keyhole Software","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/68be341bef51b95ced09befd6a7e0ca930461d95f3a64285e03e7925b8f5de47?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/68be341bef51b95ced09befd6a7e0ca930461d95f3a64285e03e7925b8f5de47?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/68be341bef51b95ced09befd6a7e0ca930461d95f3a64285e03e7925b8f5de47?s=96&d=mm&r=g","caption":"Keyhole Software"},"description":"Keyhole is a midwest-based consulting firm with a tight-knit technical team. We work primarily with Java, JavaScript and .NET technologies, specializing in application development. We love the challenge that comes in consulting and blog often regarding some of the technical situations and technologies we face.","sameAs":["http:\/\/keyholesoftware.com\/","http:\/\/facebook.com\/keyholesoftware","http:\/\/linkedin.com\/company\/keyhole-software","https:\/\/x.com\/http:\/\/twitter.com\/keyholesoftware"],"url":"https:\/\/www.javacodegeeks.com\/author\/keyhole-software"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/27861","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/471"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=27861"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/27861\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/148"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=27861"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=27861"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=27861"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}