I am trying to create an annotation by combining annother's functionality. Let's say as below:
#Documented
#Retention(RUNTIME)
#Target({TYPE, METHOD})
#Around
#io.micronaut.tracing.annotation.NewSpan
public #interface NewSpan {
String value() default "";
}
Now it's seems impossible to pass the value to io.micronaut.tracing.annotation.NewSpan, after searching many other answers and java docs, it seems impossible to me, any help.
So when I use my #NewSpan("val"), it should be passed down to io.micronaut.tracing.annotation.NewSpan's value.
Thanks!
I believe that should be the same as in spring
#Documented
#Retention(RUNTIME)
#Target({TYPE, METHOD})
#Around
#io.micronaut.tracing.annotation.NewSpan
public #interface NewSpan {
#AliasFor(annotation = io.micronaut.tracing.annotation.NewSpan.class, member="value")
String value() default "";
}
Related
I use several #PreAuthorize-base annotations for protecting my REST API methods.
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#PreAuthorize("hasRole('ROLE_A') or hasRole('ROLE_B')")
public #interface ForAorB {
}
and at the same time I have
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#PreAuthorize("hasRole('ROLE_A')")
public #interface ForA {
}
and
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#PreAuthorize("hasRole('ROLE_B')")
public #interface ForB {
}
My #PreAuthorize expressions are a bit more complex than simple hasRole('ROLE_x) and I would like not to doubling them both in #ForA, #ForB and in #ForAorB.
Whether it possible to create #ForAorB annotation bases on #ForA and #ForB and not expressions doubling in #PreAuthorize("hasRole('ROLE_A') or hasRole('ROLE_B')")?
I tried this but looks like
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#ForA #ForB
public #interface ForAorB {
}
works actually as #ForAandB but not #ForAorB
That won't work, because annotations (at least in this case) are "additive". A single #PreAuthorize annotation will give you OK or NOK, and that determines the whole outcome regardless of any other possible auth annotations.
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#ForA #ForB
public #interface ForAorB {
}
is the same as
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#PreAuthorize("hasRole('ROLE_A')")
#PreAuthorize("hasRole('ROLE_B')")
public #interface ForAorB {
}
So for AND it works, but you can't get it to work with OR except writing the #PreAuthorize annotation by hand.
I'm creating some annotations, and one of them I trying to enable to annotate twice. I use #Repeatable and created the conteiner. But when I use the annotation twice it appears that it needs to use #Repeatable.
As shown in the image below:
Message error: Duplicate annotation of non-repeatable type #TX2Value. Only annotation types marked #Repeatable can be used multiple times at one target.
#Repeatable(TX2ValueContainer.class)
#Retention(RUNTIME)
#Target({ FIELD, METHOD, ANNOTATION_TYPE, TYPE_USE })
public #interface TX2Value {
String name();
...
}
#Retention(RUNTIME)
#Target({ FIELD, METHOD, ANNOTATION_TYPE, TYPE_USE })
#interface TX2ValueContainer {
TX2Value[] value();
}
public void TestA() {
#TX2Value(name="test01")
#TX2Value(name="test02")
private String value;
}
The #Parameters annotation implementation from org.testng.annotations looks like this:
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
public #interface Parameters {
String[] value() default {};
}
So, it should allow me to use it on a ElementType.TYPE => it could also be used on a class.
When I use it on a method, I simply take the value using:
#Parameters("value")
public void m(String value) {
...
}
But if I use
#Parameters("value")
public class A {
...
}
how can I get the value inside the class?
If you want to use it for initialising class variables you can put in on constructor of class and use it.
ElementType.TYPE also means applicable to interfaces and enums - may be that one is specified if you want to extend the annotation.
My question is related to Java: Annotated Annotations (and passing values), but not entirely the same, so I thought I'd ask anyway. Especially since there were so few answers to that question.
Say I have written an annotation like this:
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE})
public #interface NestedAnnotation {
public String value();
public Class<?> impl() default Void.class;
}
So if I want to use this, I have to do something like #NestedAnnotation("somevalue"). Now, what if I want to put that annotation inside another one:
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#NestedAnnotation("need value here!")
public #interface OuterAnnotation {
public String value();
public Class<?> impl() default Void.class;
}
The NestedAnnotation needs a value, and adding a String (like above) works. But what if I wanted to pass on a value that was received by the OuterAnnotation? Is that possible?
I have written below the Custom Annotation.
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotation {
String value();
}
and am using the annotation as below.
#MyAnnotation("someValue")
public void someMethod(){
}
above code is working fine without any issues.
But in the annotation class, value() method name i have to reanme. Can i do as below?
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotation {
String name();
}
I tried doing but eclipse is giving the compilation error.
- The attribute value is undefined for the annotation type
MyAnnotation
- The annotation #MyAnnotation must define the attribute
name
Any reason?
Use it like this :
#MyAnnotation(name="someValue")
public void someMethod(){
}
because by default annotation has value method so if you specify like this
#MyAnnotation("someValue")
public void someMethod(){
}
it will by default take it as value="someValue"