merge multiple annotations with parameters
Asked Answered
P

3

14

I have a problem with using multiple annotations that all say more or less the same thing but to different frameworks and I would like to group them all into one custom annotation. Currently it looks like this:

@Column(name = "bank_account_holder_name")
@XmlElement(name = "bank_account_holder_name")
@SerializedName("bank_account_holder_name")
@ApiModelProperty(name = "bank_account_holder_name", value = "The name of the recipient bank account holder")
public String bankAccountHolderName;

As you can see they all repeat the same String and I would like to combine them, but I have yet to find a way of doing so.

Is it at all possible to do this, or do I have to either continue doing this or change/create a new framework?

Palila answered 28/4, 2017 at 11:53 Comment(1)
I'm late to the party and this is not directly an answer to your question, but I would suggest to declare a constant static final String ENTITY_NAME = "bank_account_holder_name"; that you can use in all the annotation declarations.Metalepsis
I
10

The answer is: probably no, this is not possible (using "standard" java).

You see, there is no inheritance for annotations, let alone "multiple" inheritance which would allow you to express:

public @interface MultiAnnotiation extends Column, XmlElement, ...

And most likely, those annotations work like this: at runtime the corresponding frameworks uses reflection to check if a certain object has that annotation. And if it doesn't find "its" annotation, nothing happens.

So you would need a way to "magically" insert those annotations into your class file.

Boiling down to: when you would write your own compiler, and invent something on top of java, then you could do something like that.

Things might be different when dealing with annotations that come with compiler-plugins (meaning: an annotation that is processed at compile time). Maybe you could write your own custom annotation then that triggers the same compile-time operations.

Long story short: all of this sounds interesting, but rather advanced, and most likely: not resulting in robust, production-worthy code!

Interpleader answered 28/4, 2017 at 11:58 Comment(2)
And I assume it won't work magically with something along the ways of: @Culumn(name = magic) public @interface CustomInterface ?Palila
That would annotate the annotation. That doesnt mean that something annotated with CustomInterface would see the Column annotation.Interpleader
F
9

It is possible to merge some annotations to only one annotation. Spring for example do it in the SpringBootApplication-Annotation:

/**
 * Indicates a {@link Configuration configuration} class that declares one or more
 * {@link Bean @Bean} methods and also triggers {@link EnableAutoConfiguration
 * auto-configuration} and {@link ComponentScan component scanning}. This is a convenience
 * annotation that is equivalent to declaring {@code @Configuration},
 * {@code @EnableAutoConfiguration} and {@code @ComponentScan}.
 *
 * @author Phillip Webb
 * @since 1.2.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {

    /**
     * Exclude specific auto-configuration classes such that they will never be applied.
     * @return the classes to exclude
     */
    Class<?>[] exclude() default {};

}

But i don't know if it is possible to set a value to the inner annotations from the merged annotation.

Fogle answered 28/4, 2017 at 12:4 Comment(3)
The question is in the end: how does the spring framework do that ... probably by knowing what this annotation means; and by specifically doing something about it.Interpleader
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) see the last thing...Helianthus
it's possible if you are using Spring framework >= 4.2. There is an specific annotatino - @AliasFor. link for detailsVevay
H
0

You can actually do that (at least I´ve used for TestCases annotations).

Check the article from here: https://www.swtestacademy.com/how-to-merge-multiple-annotations-in-java/

Just create a new @interface including the annotations you need.

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Column(name = "bank_account_holder_name")
@XmlElement(name = "bank_account_holder_name")
@SerializedName("bank_account_holder_name")
@ApiModelProperty(name = "bank_account_holder_name", value = "The name of the recipient bank account holder")
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCoolAnnotation {
}
Hermaphroditus answered 9/5, 2023 at 12:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.