@ManagedOperationParameter declares @Target/@Retention/@Documented/@Repeatable now

This also turns @ManagedNotification into a repeatable annotation and consistently applies findAnnotation/getRepeatableAnnotations.

Issue: SPR-13700
This commit is contained in:
Juergen Hoeller
2015-11-24 17:37:51 +01:00
parent 0524f3a474
commit 3aefc96593
10 changed files with 94 additions and 97 deletions

View File

@@ -17,8 +17,12 @@
package org.springframework.jmx.export.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Set;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.annotation.AnnotationBeanUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
@@ -26,25 +30,19 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.jmx.export.metadata.InvalidMetadataException;
import org.springframework.jmx.export.metadata.JmxAttributeSource;
import org.springframework.jmx.export.metadata.ManagedAttribute;
import org.springframework.jmx.export.metadata.ManagedMetric;
import org.springframework.jmx.export.metadata.ManagedNotification;
import org.springframework.jmx.export.metadata.ManagedOperation;
import org.springframework.jmx.export.metadata.ManagedOperationParameter;
import org.springframework.jmx.export.metadata.ManagedResource;
import org.springframework.util.StringValueResolver;
/**
* Implementation of the {@code JmxAttributeSource} interface that
* reads JDK 1.5+ annotations and exposes the corresponding attributes.
* reads annotations and exposes the corresponding attributes.
*
* @author Rob Harrop
* @author Juergen Hoeller
* @author Jennifer Hickey
* @since 1.2
* @see org.springframework.jmx.export.annotation.ManagedResource
* @see org.springframework.jmx.export.annotation.ManagedAttribute
* @see org.springframework.jmx.export.annotation.ManagedOperation
* @see ManagedResource
* @see ManagedAttribute
* @see ManagedOperation
*/
public class AnnotationJmxAttributeSource implements JmxAttributeSource, BeanFactoryAware {
@@ -66,25 +64,23 @@ public class AnnotationJmxAttributeSource implements JmxAttributeSource, BeanFac
}
@Override
public ManagedResource getManagedResource(Class<?> beanClass) throws InvalidMetadataException {
org.springframework.jmx.export.annotation.ManagedResource ann =
AnnotationUtils.getAnnotation(beanClass, org.springframework.jmx.export.annotation.ManagedResource.class);
public org.springframework.jmx.export.metadata.ManagedResource getManagedResource(Class<?> beanClass) throws InvalidMetadataException {
ManagedResource ann = AnnotationUtils.findAnnotation(beanClass, ManagedResource.class);
if (ann == null) {
return null;
}
ManagedResource managedResource = new ManagedResource();
org.springframework.jmx.export.metadata.ManagedResource managedResource = new org.springframework.jmx.export.metadata.ManagedResource();
AnnotationBeanUtils.copyPropertiesToBean(ann, managedResource, this.embeddedValueResolver);
return managedResource;
}
@Override
public ManagedAttribute getManagedAttribute(Method method) throws InvalidMetadataException {
org.springframework.jmx.export.annotation.ManagedAttribute ann =
AnnotationUtils.findAnnotation(method, org.springframework.jmx.export.annotation.ManagedAttribute.class);
public org.springframework.jmx.export.metadata.ManagedAttribute getManagedAttribute(Method method) throws InvalidMetadataException {
ManagedAttribute ann = AnnotationUtils.findAnnotation(method, ManagedAttribute.class);
if (ann == null) {
return null;
}
ManagedAttribute managedAttribute = new ManagedAttribute();
org.springframework.jmx.export.metadata.ManagedAttribute managedAttribute = new org.springframework.jmx.export.metadata.ManagedAttribute();
AnnotationBeanUtils.copyPropertiesToBean(ann, managedAttribute, "defaultValue");
if (ann.defaultValue().length() > 0) {
managedAttribute.setDefaultValue(ann.defaultValue());
@@ -93,65 +89,53 @@ public class AnnotationJmxAttributeSource implements JmxAttributeSource, BeanFac
}
@Override
public ManagedMetric getManagedMetric(Method method) throws InvalidMetadataException {
org.springframework.jmx.export.annotation.ManagedMetric ann =
AnnotationUtils.findAnnotation(method, org.springframework.jmx.export.annotation.ManagedMetric.class);
if (ann == null) {
return null;
}
ManagedMetric managedMetric = new ManagedMetric();
AnnotationBeanUtils.copyPropertiesToBean(ann, managedMetric);
return managedMetric;
public org.springframework.jmx.export.metadata.ManagedMetric getManagedMetric(Method method) throws InvalidMetadataException {
ManagedMetric ann = AnnotationUtils.findAnnotation(method, ManagedMetric.class);
return copyPropertiesToBean(ann, org.springframework.jmx.export.metadata.ManagedMetric.class);
}
@Override
public ManagedOperation getManagedOperation(Method method) throws InvalidMetadataException {
Annotation ann = AnnotationUtils.findAnnotation(method, org.springframework.jmx.export.annotation.ManagedOperation.class);
if (ann == null) {
return null;
}
ManagedOperation op = new ManagedOperation();
AnnotationBeanUtils.copyPropertiesToBean(ann, op);
return op;
public org.springframework.jmx.export.metadata.ManagedOperation getManagedOperation(Method method) throws InvalidMetadataException {
ManagedOperation ann = AnnotationUtils.findAnnotation(method, ManagedOperation.class);
return copyPropertiesToBean(ann, org.springframework.jmx.export.metadata.ManagedOperation.class);
}
@Override
public ManagedOperationParameter[] getManagedOperationParameters(Method method)
public org.springframework.jmx.export.metadata.ManagedOperationParameter[] getManagedOperationParameters(Method method)
throws InvalidMetadataException {
ManagedOperationParameters params = AnnotationUtils.findAnnotation(method, ManagedOperationParameters.class);
ManagedOperationParameter[] result = null;
if (params == null) {
result = new ManagedOperationParameter[0];
}
else {
Annotation[] paramData = params.value();
result = new ManagedOperationParameter[paramData.length];
for (int i = 0; i < paramData.length; i++) {
Annotation annotation = paramData[i];
ManagedOperationParameter managedOperationParameter = new ManagedOperationParameter();
AnnotationBeanUtils.copyPropertiesToBean(annotation, managedOperationParameter);
result[i] = managedOperationParameter;
}
}
return result;
Set<ManagedOperationParameter> anns = AnnotationUtils.getRepeatableAnnotations(
method, ManagedOperationParameter.class, ManagedOperationParameters.class);
return copyPropertiesToBeanArray(anns, org.springframework.jmx.export.metadata.ManagedOperationParameter.class);
}
@Override
public ManagedNotification[] getManagedNotifications(Class<?> clazz) throws InvalidMetadataException {
ManagedNotifications notificationsAnn = AnnotationUtils.getAnnotation(clazz, ManagedNotifications.class);
if (notificationsAnn == null) {
return new ManagedNotification[0];
public org.springframework.jmx.export.metadata.ManagedNotification[] getManagedNotifications(Class<?> clazz)
throws InvalidMetadataException {
Set<ManagedNotification> anns = AnnotationUtils.getRepeatableAnnotations(
clazz, ManagedNotification.class, ManagedNotifications.class);
return copyPropertiesToBeanArray(anns, org.springframework.jmx.export.metadata.ManagedNotification.class);
}
@SuppressWarnings("unchecked")
private static <T> T[] copyPropertiesToBeanArray(Collection<? extends Annotation> anns, Class<T> beanClass) {
T[] beans = (T[]) Array.newInstance(beanClass, anns.size());
int i = 0;
for (Annotation ann : anns) {
beans[i++] = copyPropertiesToBean(ann, beanClass);
}
Annotation[] notifications = notificationsAnn.value();
ManagedNotification[] result = new ManagedNotification[notifications.length];
for (int i = 0; i < notifications.length; i++) {
Annotation notification = notifications[i];
ManagedNotification managedNotification = new ManagedNotification();
AnnotationBeanUtils.copyPropertiesToBean(notification, managedNotification);
result[i] = managedNotification;
return beans;
}
private static <T> T copyPropertiesToBean(Annotation ann, Class<T> beanClass) {
if (ann == null) {
return null;
}
return result;
T bean = BeanUtils.instantiate(beanClass);
AnnotationBeanUtils.copyPropertiesToBean(ann, bean);
return bean;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2005 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,8 +23,8 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* JDK 1.5+ method-level annotation that indicates to expose a given bean
* property as JMX attribute, corresponding to the ManagedAttribute attribute.
* Method-level annotation that indicates to expose a given bean property as a
* JMX attribute, corresponding to the {@code ManagedAttribute} attribute.
* Only valid when used on a JavaBean getter or setter.
*
* @author Rob Harrop

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,9 +25,9 @@ import java.lang.annotation.Target;
import org.springframework.jmx.support.MetricType;
/**
* JDK 1.5+ method-level annotation that indicates to expose a given bean
* property as JMX attribute, with added Descriptor properties to indicate that
* it is a metric. Only valid when used on a JavaBean getter.
* Method-level annotation that indicates to expose a given bean property as a
* JMX attribute, with added descriptor properties to indicate that it is a metric.
* Only valid when used on a JavaBean getter.
*
* @author Jennifer Hickey
* @since 3.0

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,13 +19,15 @@ package org.springframework.jmx.export.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* JDK 1.5+ method-level annotation that indicates a JMX notification
* emitted by a bean.
* Type-level annotation that indicates a JMX notification emitted by a bean.
*
* <p>As of Spring Framework 4.2.4, this annotation is declared as repeatable.
*
* @author Rob Harrop
* @since 2.0
@@ -35,6 +37,7 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Repeatable(ManagedNotifications.class)
public @interface ManagedNotification {
String name();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,8 +24,8 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* JDK 1.5+ method-level annotation that indicates JMX notifications emitted by
* a bean, containing multiple {@link ManagedNotification ManagedNotifications}
* Type-level annotation that indicates JMX notifications emitted by a bean,
* containing multiple {@link ManagedNotification ManagedNotifications}
*
* @author Rob Harrop
* @since 2.0

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2005 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,8 +23,8 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* JDK 1.5+ method-level annotation that indicates to expose a given method
* as JMX operation, corresponding to the ManagedOperation attribute.
* Method-level annotation that indicates to expose a given method as a
* JMX operation, corresponding to the {@code ManagedOperation} attribute.
* Only valid when used on a method that is not a JavaBean getter or setter.
*
* @author Rob Harrop

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,29 @@
package org.springframework.jmx.export.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* JDK 1.5+ method-level annotation used to provide metadata about operation
* parameters, corresponding to a {@code ManagedOperationParameter} attribute.
* Used as part of a {@code ManagedOperationParameters} annotation.
* Method-level annotation used to provide metadata about operation parameters,
* corresponding to a {@code ManagedOperationParameter} attribute.
* Used as part of a {@link ManagedOperationParameters} annotation.
*
* <p>As of Spring Framework 4.2.4, this annotation is declared as repeatable.
*
* @author Rob Harrop
* @since 1.2
* @see ManagedOperationParameters#value
* @see org.springframework.jmx.export.metadata.ManagedOperationParameter
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(ManagedOperationParameters.class)
public @interface ManagedOperationParameter {
String name();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,9 +23,8 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* JDK 1.5+ method-level annotation used to provide metadata about
* operation parameters, corresponding to an array of
* {@code ManagedOperationParameter} attributes.
* Method-level annotation used to provide metadata about operation parameters,
* corresponding to an array of {@code ManagedOperationParameter} attributes.
*
* @author Rob Harrop
* @since 1.2

View File

@@ -26,8 +26,8 @@ import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/**
* JDK 1.5+ class-level annotation that indicates to register instances of a
* class with a JMX server, corresponding to the ManagedResource attribute.
* Class-level annotation that indicates to register instances of a class
* with a JMX server, corresponding to the {@code ManagedResource} attribute.
*
* <p><b>Note:</b> This annotation is marked as inherited, allowing for generic
* management-aware base classes. In such a scenario, it is recommended to