Skip to content

Commit 1af6480

Browse files
committed
Revise reference documentation for Spring JMX annotations
This commit revises the reference documentation for Spring JMX annotations for various reasons including, but not limited to, the following. - Type names such as ManagedResource are often ambiguous, especially when discussing an annotation like @⁠ManagedResource instead of org.springframework.jmx.export.metadata.ManagedResource which is a class. - AnnotationTestBean implements IJmxTestBean, even though an annotated MBean is not required to implement any interfaces, and in fact the example is meant to demonstrate that an annotated POJO suffices. - @⁠ManagedOperationParameter annotations are unnecessarily declared in the @⁠ManagedOperationParameters container. - The documentation sometimes refers to JmxTestBean when it should instead refer to AnnotationTestBean. - Inconsistent and confusing wording for annotation attributes, properties, managed attributes, etc. - The tables refer to "source-level metadata types/parameters" when they should refer to Spring JMX annotations and their attributes. - The annotation and attribute tables have inconsistent ordering and naming for column headers. - @⁠ManagedNotification and @⁠ManagedMetric are not mentioned. - The AutodetectCapableMBeanInfoAssembler example is broken since it uses the non-annotated JmxTestBean instead of the AnnotationTestBean. As a side note, the JmxTestBean in our test suite still contains XDoclet "annotations" which can be safely removed. 😉 Closes gh-33466
1 parent 6e640f0 commit 1af6480

File tree

9 files changed

+191
-222
lines changed

9 files changed

+191
-222
lines changed

framework-docs/modules/ROOT/pages/integration/jmx/interface.adoc

Lines changed: 103 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ controlling the management interfaces of your beans.
1111

1212

1313
[[jmx-interface-assembler]]
14-
== Using the `MBeanInfoAssembler` Interface
14+
== Using the `MBeanInfoAssembler` API
1515

1616
Behind the scenes, the `MBeanExporter` delegates to an implementation of the
17-
`org.springframework.jmx.export.assembler.MBeanInfoAssembler` interface, which is
17+
`org.springframework.jmx.export.assembler.MBeanInfoAssembler` API, which is
1818
responsible for defining the management interface of each bean that is exposed.
1919
The default implementation,
2020
`org.springframework.jmx.export.assembler.SimpleReflectiveMBeanInfoAssembler`,
@@ -28,35 +28,31 @@ or any arbitrary interface.
2828
[[jmx-interface-metadata]]
2929
== Using Source-level Metadata: Java Annotations
3030

31-
By using the `MetadataMBeanInfoAssembler`, you can define the management interfaces
32-
for your beans by using source-level metadata. The reading of metadata is encapsulated
33-
by the `org.springframework.jmx.export.metadata.JmxAttributeSource` interface.
34-
Spring JMX provides a default implementation that uses Java annotations, namely
35-
`org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource`.
36-
You must configure the `MetadataMBeanInfoAssembler` with an implementation instance of
37-
the `JmxAttributeSource` interface for it to function correctly (there is no default).
31+
By using the `MetadataMBeanInfoAssembler`, you can define the management interfaces for
32+
your beans by using source-level metadata. The reading of metadata is encapsulated by the
33+
`org.springframework.jmx.export.metadata.JmxAttributeSource` interface. Spring JMX
34+
provides a default implementation that uses Java annotations, namely
35+
`org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource`. You must
36+
configure the `MetadataMBeanInfoAssembler` with an implementation instance of the
37+
`JmxAttributeSource` interface for it to function correctly, since there is no default.
3838

3939
To mark a bean for export to JMX, you should annotate the bean class with the
40-
`ManagedResource` annotation. You must mark each method you wish to expose as an operation
41-
with the `ManagedOperation` annotation and mark each property you wish to expose
42-
with the `ManagedAttribute` annotation. When marking properties, you can omit
40+
`@ManagedResource` annotation. You must annotate each method you wish to expose as an
41+
operation with the `@ManagedOperation` annotation and annotate each property you wish to
42+
expose with the `@ManagedAttribute` annotation. When annotating properties, you can omit
4343
either the annotation of the getter or the setter to create a write-only or read-only
4444
attribute, respectively.
4545

46-
NOTE: A `ManagedResource`-annotated bean must be public, as must the methods exposing
47-
an operation or an attribute.
46+
NOTE: A `@ManagedResource`-annotated bean must be public, as must the methods exposing
47+
operations or attributes.
4848

49-
The following example shows the annotated version of the `JmxTestBean` class that we
50-
used in xref:integration/jmx/exporting.adoc#jmx-exporting-mbeanserver[Creating an MBeanServer]:
49+
The following example shows an annotated version of the `JmxTestBean` class that we
50+
used in xref:integration/jmx/exporting.adoc#jmx-exporting-mbeanserver[Creating an MBeanServer].
5151

5252
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
5353
----
5454
package org.springframework.jmx;
5555
56-
import org.springframework.jmx.export.annotation.ManagedResource;
57-
import org.springframework.jmx.export.annotation.ManagedOperation;
58-
import org.springframework.jmx.export.annotation.ManagedAttribute;
59-
6056
@ManagedResource(
6157
objectName="bean:name=testBean4",
6258
description="My Managed Bean",
@@ -67,20 +63,20 @@ used in xref:integration/jmx/exporting.adoc#jmx-exporting-mbeanserver[Creating a
6763
persistPeriod=200,
6864
persistLocation="foo",
6965
persistName="bar")
70-
public class AnnotationTestBean implements IJmxTestBean {
66+
public class AnnotationTestBean {
7167
72-
private String name;
7368
private int age;
74-
75-
@ManagedAttribute(description="The Age Attribute", currencyTimeLimit=15)
76-
public int getAge() {
77-
return age;
78-
}
69+
private String name;
7970
8071
public void setAge(int age) {
8172
this.age = age;
8273
}
8374
75+
@ManagedAttribute(description="The Age Attribute", currencyTimeLimit=15)
76+
public int getAge() {
77+
return this.age;
78+
}
79+
8480
@ManagedAttribute(description="The Name Attribute",
8581
currencyTimeLimit=20,
8682
defaultValue="bar",
@@ -91,13 +87,12 @@ used in xref:integration/jmx/exporting.adoc#jmx-exporting-mbeanserver[Creating a
9187
9288
@ManagedAttribute(defaultValue="foo", persistPeriod=300)
9389
public String getName() {
94-
return name;
90+
return this.name;
9591
}
9692
9793
@ManagedOperation(description="Add two numbers")
98-
@ManagedOperationParameters({
99-
@ManagedOperationParameter(name = "x", description = "The first number"),
100-
@ManagedOperationParameter(name = "y", description = "The second number")})
94+
@ManagedOperationParameter(name = "x", description = "The first number")
95+
@ManagedOperationParameter(name = "y", description = "The second number")
10196
public int add(int x, int y) {
10297
return x + y;
10398
}
@@ -109,36 +104,37 @@ used in xref:integration/jmx/exporting.adoc#jmx-exporting-mbeanserver[Creating a
109104
}
110105
----
111106

112-
In the preceding example, you can see that the `JmxTestBean` class is marked with the
113-
`ManagedResource` annotation and that this `ManagedResource` annotation is configured
114-
with a set of properties. These properties can be used to configure various aspects
107+
In the preceding example, you can see that the `AnnotationTestBean` class is annotated
108+
with `@ManagedResource` and that this `@ManagedResource` annotation is configured
109+
with a set of attributes. These attributes can be used to configure various aspects
115110
of the MBean that is generated by the `MBeanExporter` and are explained in greater
116-
detail later in xref:integration/jmx/interface.adoc#jmx-interface-metadata-types[Source-level Metadata Types].
111+
detail later in xref:integration/jmx/interface.adoc#jmx-interface-metadata-types[Spring JMX Annotations].
117112

118-
Both the `age` and `name` properties are annotated with the `ManagedAttribute`
119-
annotation, but, in the case of the `age` property, only the getter is marked.
113+
Both the `age` and `name` properties are annotated with `@ManagedAttribute`,
114+
but, in the case of the `age` property, only the getter method is annotated.
120115
This causes both of these properties to be included in the management interface
121-
as attributes, but the `age` attribute is read-only.
116+
as managed attributes, but the `age` attribute is read-only.
122117

123-
Finally, the `add(int, int)` method is marked with the `ManagedOperation` attribute,
118+
Finally, the `add(int, int)` method is annotated with `@ManagedOperation`,
124119
whereas the `dontExposeMe()` method is not. This causes the management interface to
125120
contain only one operation (`add(int, int)`) when you use the `MetadataMBeanInfoAssembler`.
126121

122+
NOTE: The `AnnotationTestBean` class is not required to implement any Java interfaces,
123+
since the JMX management interface is derived solely from annotations.
124+
127125
The following configuration shows how you can configure the `MBeanExporter` to use the
128126
`MetadataMBeanInfoAssembler`:
129127

130128
[source,xml,indent=0,subs="verbatim,quotes"]
131129
----
132130
<beans>
131+
133132
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
134133
<property name="assembler" ref="assembler"/>
135134
<property name="namingStrategy" ref="namingStrategy"/>
136135
<property name="autodetect" value="true"/>
137136
</bean>
138137
139-
<bean id="jmxAttributeSource"
140-
class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
141-
142138
<!-- will create management interface using annotation metadata -->
143139
<bean id="assembler"
144140
class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
@@ -151,102 +147,116 @@ The following configuration shows how you can configure the `MBeanExporter` to u
151147
<property name="attributeSource" ref="jmxAttributeSource"/>
152148
</bean>
153149
150+
<bean id="jmxAttributeSource"
151+
class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
152+
154153
<bean id="testBean" class="org.springframework.jmx.AnnotationTestBean">
155154
<property name="name" value="TEST"/>
156155
<property name="age" value="100"/>
157156
</bean>
157+
158158
</beans>
159159
----
160160

161-
In the preceding example, an `MetadataMBeanInfoAssembler` bean has been configured with an
161+
In the preceding example, a `MetadataMBeanInfoAssembler` bean has been configured with an
162162
instance of the `AnnotationJmxAttributeSource` class and passed to the `MBeanExporter`
163163
through the assembler property. This is all that is required to take advantage of
164-
metadata-driven management interfaces for your Spring-exposed MBeans.
164+
annotation-driven management interfaces for your Spring-exposed MBeans.
165165

166166

167167
[[jmx-interface-metadata-types]]
168-
== Source-level Metadata Types
168+
== Spring JMX Annotations
169169

170-
The following table describes the source-level metadata types that are available for use in Spring JMX:
170+
The following table describes the annotations that are available for use in Spring JMX:
171171

172172
[[jmx-metadata-types]]
173-
.Source-level metadata types
173+
.Spring JMX annotations
174+
[cols="1,1,3"]
174175
|===
175-
| Purpose| Annotation| Annotation Type
176+
| Annotation | Applies to | Description
176177

177-
| Mark all instances of a `Class` as JMX managed resources.
178178
| `@ManagedResource`
179-
| Class
179+
| Classes
180+
| Marks all instances of a `Class` as JMX managed resources.
180181

181-
| Mark a method as a JMX operation.
182-
| `@ManagedOperation`
183-
| Method
182+
| `@ManagedNotification`
183+
| Classes
184+
| Indicates a JMX notification emitted by a managed resource.
184185

185-
| Mark a getter or setter as one half of a JMX attribute.
186186
| `@ManagedAttribute`
187-
| Method (only getters and setters)
187+
| Methods (only getters and setters)
188+
| Marks a getter or setter as one half of a JMX attribute.
188189

189-
| Define descriptions for operation parameters.
190-
| `@ManagedOperationParameter` and `@ManagedOperationParameters`
191-
| Method
190+
| `@ManagedMetric`
191+
| Methods (only getters)
192+
| Marks a getter as a JMX attribute, with added descriptor properties to indicate that it is a metric.
193+
194+
| `@ManagedOperation`
195+
| Methods
196+
| Marks a method as a JMX operation.
197+
198+
| `@ManagedOperationParameter`
199+
| Methods
200+
| Defines a description for an operation parameter.
192201
|===
193202

194-
The following table describes the configuration parameters that are available for use on these source-level
195-
metadata types:
203+
The following table describes some of the common attributes that are available for use in
204+
these annotations. Consult the Javadoc for each annotation for further details.
196205

197206
[[jmx-metadata-parameters]]
198-
.Source-level metadata parameters
199-
[cols="1,3,1"]
207+
.Spring JMX annotation attributes
208+
[cols="1,1,3"]
200209
|===
201-
| Parameter | Description | Applies to
210+
| Attribute | Applies to | Description
202211

203-
| `ObjectName`
212+
| `objectName`
213+
| `@ManagedResource`
204214
| Used by `MetadataNamingStrategy` to determine the `ObjectName` of a managed resource.
205-
| `ManagedResource`
206215

207216
| `description`
208-
| Sets the friendly description of the resource, attribute or operation.
209-
| `ManagedResource`, `ManagedAttribute`, `ManagedOperation`, or `ManagedOperationParameter`
217+
| `@ManagedResource`, `@ManagedNotification`, `@ManagedAttribute`, `@ManagedMetric`,
218+
`@ManagedOperation`, `@ManagedOperationParameter`
219+
| Sets the description of the resource, notification, attribute, metric, or operation.
210220

211221
| `currencyTimeLimit`
222+
| `@ManagedResource`, `@ManagedAttribute`, `@ManagedMetric`
212223
| Sets the value of the `currencyTimeLimit` descriptor field.
213-
| `ManagedResource` or `ManagedAttribute`
214224

215225
| `defaultValue`
226+
| `@ManagedAttribute`
216227
| Sets the value of the `defaultValue` descriptor field.
217-
| `ManagedAttribute`
218228

219229
| `log`
230+
| `@ManagedResource`
220231
| Sets the value of the `log` descriptor field.
221-
| `ManagedResource`
222232

223233
| `logFile`
234+
| `@ManagedResource`
224235
| Sets the value of the `logFile` descriptor field.
225-
| `ManagedResource`
226236

227237
| `persistPolicy`
238+
| `@ManagedResource`, `@ManagedMetric`
228239
| Sets the value of the `persistPolicy` descriptor field.
229-
| `ManagedResource`
230240

231241
| `persistPeriod`
242+
| `@ManagedResource`, `@ManagedMetric`
232243
| Sets the value of the `persistPeriod` descriptor field.
233-
| `ManagedResource`
234244

235245
| `persistLocation`
246+
| `@ManagedResource`
236247
| Sets the value of the `persistLocation` descriptor field.
237-
| `ManagedResource`
238248

239249
| `persistName`
250+
| `@ManagedResource`
240251
| Sets the value of the `persistName` descriptor field.
241-
| `ManagedResource`
242252

243253
| `name`
254+
| `@ManagedOperationParameter`
244255
| Sets the display name of an operation parameter.
245-
| `ManagedOperationParameter`
246256

247257
| `index`
258+
| `@ManagedOperationParameter`
248259
| Sets the index of an operation parameter.
249-
| `ManagedOperationParameter`
250260
|===
251261

252262

@@ -255,14 +265,14 @@ metadata types:
255265

256266
To simplify configuration even further, Spring includes the
257267
`AutodetectCapableMBeanInfoAssembler` interface, which extends the `MBeanInfoAssembler`
258-
interface to add support for autodetection of MBean resources. If you configure the
268+
interface to add support for auto-detection of MBean resources. If you configure the
259269
`MBeanExporter` with an instance of `AutodetectCapableMBeanInfoAssembler`, it is
260-
allowed to "`vote`" on the inclusion of beans for exposure to JMX.
270+
allowed to "vote" on the inclusion of beans for exposure to JMX.
261271

262272
The only implementation of the `AutodetectCapableMBeanInfo` interface is
263273
the `MetadataMBeanInfoAssembler`, which votes to include any bean that is marked
264274
with the `ManagedResource` attribute. The default approach in this case is to use the
265-
bean name as the `ObjectName`, which results in a configuration similar to the following:
275+
bean name as the `ObjectName`, which results in configuration similar to the following:
266276

267277
[source,xml,indent=0,subs="verbatim,quotes"]
268278
----
@@ -274,26 +284,29 @@ bean name as the `ObjectName`, which results in a configuration similar to the f
274284
<property name="assembler" ref="assembler"/>
275285
</bean>
276286
277-
<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
278-
<property name="name" value="TEST"/>
279-
<property name="age" value="100"/>
280-
</bean>
281-
282287
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
283288
<property name="attributeSource">
284289
<bean class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
285290
</property>
286291
</bean>
287292
293+
<bean id="testBean" class="org.springframework.jmx.AnnotationTestBean">
294+
<property name="name" value="TEST"/>
295+
<property name="age" value="100"/>
296+
</bean>
297+
288298
</beans>
289299
----
290300

291301
Notice that, in the preceding configuration, no beans are passed to the `MBeanExporter`.
292-
However, the `JmxTestBean` is still registered, since it is marked with the `ManagedResource`
293-
attribute and the `MetadataMBeanInfoAssembler` detects this and votes to include it.
294-
The only problem with this approach is that the name of the `JmxTestBean` now has business
295-
meaning. You can address this issue by changing the default behavior for `ObjectName`
296-
creation as defined in xref:integration/jmx/naming.adoc[Controlling `ObjectName` Instances for Your Beans].
302+
However, the `AnnotationTestBean` is still registered, since it is annotated with
303+
`@ManagedResource` and the `MetadataMBeanInfoAssembler` detects this and votes to include
304+
it. The only downside with this approach is that the name of the `AnnotationTestBean` now
305+
has business meaning. You can address this issue by configuring an `ObjectNamingStrategy`
306+
as explained in xref:integration/jmx/naming.adoc[Controlling `ObjectName` Instances for
307+
Your Beans]. You can also see an example which uses the `MetadataNamingStrategy` in
308+
xref:integration/jmx/interface.adoc#jmx-interface-metadata[Using Source-level Metadata: Java Annotations].
309+
297310

298311

299312
[[jmx-interface-java]]

spring-context/src/test/java/org/springframework/jmx/IJmxTestBean.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,19 +20,15 @@
2020
* @author Rob Harrop
2121
* @author Juergen Hoeller
2222
*/
23-
public interface IJmxTestBean {
23+
public interface IJmxTestBean extends ITestBean {
2424

2525
int add(int x, int y);
2626

2727
long myOperation();
2828

29-
int getAge();
30-
3129
void setAge(int age);
3230

33-
void setName(String name) throws Exception;
34-
35-
String getName();
31+
int getAge();
3632

3733
// used to test invalid methods that exist in the proxy interface
3834
void dontExposeMe();

0 commit comments

Comments
 (0)