Retrieve Java Annotation Attribute

Retrieve Java Annotation Attribute

  1. Obtain Method instance.
  2. Obtain annotation.
  3. Obtain annotation attribute value.

Something like:

Method m = getClass().getMethod("myMethod");
MyAnnotation a = m.getAnnotation(MyAnnotation.class);
MyValueType value1 = a.attribute1();

You'll need to catch / handle the appropriate exceptions, of course. The above assumes you are indeed retrieving method from the current class (replace getClass() with Class.forName() otherwise) and the method in question is public (use getDeclaredMethods() if that's not the case)

How to get annotation class name, attribute values using reflection

Contrary to what one might expect, the elements of an annotation are not attributes - they are actually methods that return the provided value or a default value.

You have to iterate through the annotations' methods and invoke them to get the values. Use annotationType() to get the annotation's class, the object returned by getClass() is just a proxy.

Here is an example which prints all elements and their values of the @Resource annotation of a class:

@Resource(name = "foo", description = "bar")
public class Test {

public static void main(String[] args) throws Exception {

for (Annotation annotation : Test.class.getAnnotations()) {
Class<? extends Annotation> type = annotation.annotationType();
System.out.println("Values of " + type.getName());

for (Method method : type.getDeclaredMethods()) {
Object value = method.invoke(annotation, (Object[])null);
System.out.println(" " + method.getName() + ": " + value);
}
}

}
}

Output:

Values of javax.annotation.Resource
name: foo
type: class java.lang.Object
lookup:
description: bar
authenticationType: CONTAINER
mappedName:
shareable: true

Thanks to Aaron for pointing out the you need to cast the null argument to avoid warnings.

easy way to get annotation value of object member in Java

You cannot get the annotations of a field given it's value.

When you are calling your "Util" method, all you are passing it is the value of the field. It won't have enough information to access the annotation.

Here is a way you might do it...

public class SomeClass {

@Digits(fraction = 2, integer = 16)
private BigDecimal amount;

private void setAmount(double d) {
amount = BigDecimal.valueOf(d);

amount.setScale(Util.getFraction(this, "amount"));
}

public static void main(String[] args) {
new SomeClass().setAmount(12.3);
}
}

Notice I'm passing the instance of the object that the field is in and the name of the field to my "Util" method.

It can now get the actual value like this...

public class Util {

public static int getFraction(Object obj, String fieldName) {
try {
Digits annotation = obj.getClass().getDeclaredField(fieldName).getAnnotation(Digits.class);
return annotation.fraction();
} catch (NoSuchFieldException | SecurityException e) {
// BOOM!
throw new IllegalStateException("Something went awfully wrong...", e);
}
}
}

Get the Javax Validation Annotation Attribute Value

Since the annotation has a runtime retention, you can access it through reflection. For instance (ignoring any exceptions):

Field field = MyClass.class.getDeclaredField("data");
Size size = field.getAnnotation(Field.class);
int max = size.max();

If you want to get the value that triggered a constraint error, catch the ConstraintViolationException. You can then get the constraint annotation from the violation. Another example:

// just some code to get a descriptor
ConstraintDescriptor<?> descriptor = constraintViolationException.getAnnotations().stream()
.map(ConstraintViolation::getConstraintDescriptor)
.findAny()
.orElseThrow();

// now its properties can be accessed
Map<String, Object> attributes = descriptor.getAttributes();
// attributes contains an entry with key "max" and value 10 for your @Size annotation
Size size = (Size) descriptor.getAnnotation();
int max = size.max();

How do I get the method in the annotation parameter in an Aspect and get the result of the method execution

I'm the questioner

I have solved this using Java reflection,as follows:

@Aspect
@Component
public class PreVisitAspect {

@Autowired
private PageVisit pv;

@Around("@annotation(preVisit)")
public Object around(ProceedingJoinPoint joinPoint, PreVisit preVisit) throws Throwable {
String value = preVisit.value();
//String value="@pas.hasAccess('xxxxxx')";
if(value.startsWith("@")){
String beanName=value.substring(value.indexOf("@")+1,value.indexOf("."));
String methodName=value.substring(value.indexOf(".")+1,value.indexOf("("));
String paramsStr=value.substring(value.indexOf("(")+2,value.lastIndexOf(")")-1);
Object[] paramsArr=paramsStr.split("','");

logger.info("beanName:"+beanName);
logger.info("methodName:"+methodName);
logger.info("paramsStr:"+paramsStr);

ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Method method = ReflectionUtils.findMethod(appContext.getBean(beanName).getClass(), methodName,new Class[]{String.class} );
Boolean result = (Boolean)ReflectionUtils.invokeMethod(method, appContext.getBean(beanName),paramsArr);
logger.info(result.toString());
}
.....other Code.....
}
}

tks @Karthikeyan Vaithilingam

Retrieve annotation by name

Use asSubclass. Unlike compiler generated type casts, which can only work with types known at compile-time, this will perform a check against the Class object retrieved at runtime. Since this is safe, it won’t generated an “Unchecked cast” warning. Note the existence of a similar operation, cast for casting an instance of a Class. These methods were added in Java 5, specifically to aid code using Generics.

String annotationName = "java.lang.Deprecated";
Class<? extends Annotation> c = Class.forName(annotationName).asSubclass(Annotation.class);
boolean depr = Thread.class.getMethod("stop").isAnnotationPresent(c);
System.out.println(depr);

Get value of a parameter of an annotation in Java

To get value of the @Path parameter:

String path = Hello.class.getAnnotation(Path.class).value();

Similarly, Once you have hold of Method getHtml

Method m = Hello.class.getMethod("getHtml", ..);
String mime = m.getAnnotation(Produces.class).value;

Access to class attributes' values using Java Annotations

You need to iterate through the fields, get their annotations and set the value wherever the annotation matches (it can match multiple fields):

@Retention(RetentionPolicy.RUNTIME)
public @interface Field1 {}

@Retention(RetentionPolicy.RUNTIME)
public @interface Field2 {}

public static class UnderTest {

@Field1
private String field1;

@Field2
private int field2;

public UnderTest(String field1, int field2) {
this.field1 = field1;
this.field2 = field2;
}

@Override
public String toString() {
return field1 + "=" + field2;
}
}

public static void setter(Object obj, Class<? extends Annotation> fieldAnnotation, Object fieldValue) throws IllegalAccessException {
for (Field field: obj.getClass().getDeclaredFields()) {
for (Annotation annot: field.getDeclaredAnnotations()) {
if (annot.annotationType().isAssignableFrom(fieldAnnotation)) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.set(obj, fieldValue);
}
}
}
}

public static void main(String[] argv) throws IllegalAccessException {
UnderTest underTest = new UnderTest("A", 1);
System.out.println(underTest);

setter(underTest, Field1.class, "B");
setter(underTest, Field2.class, 2);
System.out.println(underTest);
}

Running this prints

A=1

B=2



Related Topics



Leave a reply



Submit