431 lines
16 KiB
Plaintext
431 lines
16 KiB
Plaintext
[[jmx-interface]]
|
|
= Controlling the Management Interface of Your Beans
|
|
|
|
In the example in the xref:integration/jmx/exporting.adoc#jmx-exporting-registration-behavior[preceding section],
|
|
you had little control over the management interface of your bean. All of the `public`
|
|
properties and methods of each exported bean were exposed as JMX attributes and
|
|
operations, respectively. To exercise finer-grained control over exactly which
|
|
properties and methods of your exported beans are actually exposed as JMX attributes
|
|
and operations, Spring JMX provides a comprehensive and extensible mechanism for
|
|
controlling the management interfaces of your beans.
|
|
|
|
|
|
[[jmx-interface-assembler]]
|
|
== Using the `MBeanInfoAssembler` API
|
|
|
|
Behind the scenes, the `MBeanExporter` delegates to an implementation of the
|
|
`org.springframework.jmx.export.assembler.MBeanInfoAssembler` API, which is
|
|
responsible for defining the management interface of each bean that is exposed.
|
|
The default implementation,
|
|
`org.springframework.jmx.export.assembler.SimpleReflectiveMBeanInfoAssembler`,
|
|
defines a management interface that exposes all public properties and methods
|
|
(as you saw in the examples in the preceding sections). Spring provides two
|
|
additional implementations of the `MBeanInfoAssembler` interface that let you
|
|
control the generated management interface by using either source-level metadata
|
|
or any arbitrary interface.
|
|
|
|
|
|
[[jmx-interface-metadata]]
|
|
== Using Source-level Metadata: Java Annotations
|
|
|
|
By using the `MetadataMBeanInfoAssembler`, you can define the management interfaces for
|
|
your beans by using source-level metadata. The reading of metadata is encapsulated by the
|
|
`org.springframework.jmx.export.metadata.JmxAttributeSource` interface. Spring JMX
|
|
provides a default implementation that uses Java annotations, namely
|
|
`org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource`. You must
|
|
configure the `MetadataMBeanInfoAssembler` with an implementation instance of the
|
|
`JmxAttributeSource` interface for it to function correctly, since there is no default.
|
|
|
|
To mark a bean for export to JMX, you should annotate the bean class with the
|
|
`@ManagedResource` annotation. You must annotate each method you wish to expose as an
|
|
operation with the `@ManagedOperation` annotation and annotate each property you wish to
|
|
expose with the `@ManagedAttribute` annotation. When annotating properties, you can omit
|
|
either the annotation of the getter or the setter to create a write-only or read-only
|
|
attribute, respectively.
|
|
|
|
NOTE: A `@ManagedResource`-annotated bean must be public, as must the methods exposing
|
|
operations or attributes.
|
|
|
|
The following example shows an annotated version of the `JmxTestBean` class that we
|
|
used in xref:integration/jmx/exporting.adoc#jmx-exporting-mbeanserver[Creating an MBeanServer].
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"]
|
|
----
|
|
package org.springframework.jmx;
|
|
|
|
@ManagedResource(
|
|
objectName="bean:name=testBean4",
|
|
description="My Managed Bean",
|
|
log=true,
|
|
logFile="jmx.log",
|
|
currencyTimeLimit=15,
|
|
persistPolicy="OnUpdate",
|
|
persistPeriod=200,
|
|
persistLocation="foo",
|
|
persistName="bar")
|
|
public class AnnotationTestBean {
|
|
|
|
private int age;
|
|
private String name;
|
|
|
|
public void setAge(int age) {
|
|
this.age = age;
|
|
}
|
|
|
|
@ManagedAttribute(description="The Age Attribute", currencyTimeLimit=15)
|
|
public int getAge() {
|
|
return this.age;
|
|
}
|
|
|
|
@ManagedAttribute(description="The Name Attribute",
|
|
currencyTimeLimit=20,
|
|
defaultValue="bar",
|
|
persistPolicy="OnUpdate")
|
|
public void setName(String name) {
|
|
this.name = name;
|
|
}
|
|
|
|
@ManagedAttribute(defaultValue="foo", persistPeriod=300)
|
|
public String getName() {
|
|
return this.name;
|
|
}
|
|
|
|
@ManagedOperation(description="Add two numbers")
|
|
@ManagedOperationParameter(name = "x", description = "The first number")
|
|
@ManagedOperationParameter(name = "y", description = "The second number")
|
|
public int add(int x, int y) {
|
|
return x + y;
|
|
}
|
|
|
|
public void dontExposeMe() {
|
|
throw new RuntimeException();
|
|
}
|
|
|
|
}
|
|
----
|
|
|
|
In the preceding example, you can see that the `AnnotationTestBean` class is annotated
|
|
with `@ManagedResource` and that this `@ManagedResource` annotation is configured
|
|
with a set of attributes. These attributes can be used to configure various aspects
|
|
of the MBean that is generated by the `MBeanExporter` and are explained in greater
|
|
detail later in xref:integration/jmx/interface.adoc#jmx-interface-metadata-types[Spring JMX Annotations].
|
|
|
|
Both the `age` and `name` properties are annotated with `@ManagedAttribute`,
|
|
but, in the case of the `age` property, only the getter method is annotated.
|
|
This causes both of these properties to be included in the management interface
|
|
as managed attributes, but the `age` attribute is read-only.
|
|
|
|
Finally, the `add(int, int)` method is annotated with `@ManagedOperation`,
|
|
whereas the `dontExposeMe()` method is not. This causes the management interface to
|
|
contain only one operation (`add(int, int)`) when you use the `MetadataMBeanInfoAssembler`.
|
|
|
|
NOTE: The `AnnotationTestBean` class is not required to implement any Java interfaces,
|
|
since the JMX management interface is derived solely from annotations.
|
|
|
|
The following configuration shows how you can configure the `MBeanExporter` to use the
|
|
`MetadataMBeanInfoAssembler`:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes"]
|
|
----
|
|
<beans>
|
|
|
|
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
|
|
<property name="assembler" ref="assembler"/>
|
|
<property name="namingStrategy" ref="namingStrategy"/>
|
|
<property name="autodetect" value="true"/>
|
|
</bean>
|
|
|
|
<!-- will create management interface using annotation metadata -->
|
|
<bean id="assembler"
|
|
class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
|
|
<property name="attributeSource" ref="jmxAttributeSource"/>
|
|
</bean>
|
|
|
|
<!-- will pick up the ObjectName from the annotation -->
|
|
<bean id="namingStrategy"
|
|
class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
|
|
<property name="attributeSource" ref="jmxAttributeSource"/>
|
|
</bean>
|
|
|
|
<bean id="jmxAttributeSource"
|
|
class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
|
|
|
|
<bean id="testBean" class="org.springframework.jmx.AnnotationTestBean">
|
|
<property name="name" value="TEST"/>
|
|
<property name="age" value="100"/>
|
|
</bean>
|
|
|
|
</beans>
|
|
----
|
|
|
|
In the preceding example, a `MetadataMBeanInfoAssembler` bean has been configured with an
|
|
instance of the `AnnotationJmxAttributeSource` class and passed to the `MBeanExporter`
|
|
through the assembler property. This is all that is required to take advantage of
|
|
annotation-driven management interfaces for your Spring-exposed MBeans.
|
|
|
|
|
|
[[jmx-interface-metadata-types]]
|
|
== Spring JMX Annotations
|
|
|
|
The following table describes the annotations that are available for use in Spring JMX:
|
|
|
|
[[jmx-metadata-types]]
|
|
.Spring JMX annotations
|
|
[cols="1,1,3"]
|
|
|===
|
|
| Annotation | Applies to | Description
|
|
|
|
| `@ManagedResource`
|
|
| Classes
|
|
| Marks all instances of a `Class` as JMX managed resources.
|
|
|
|
| `@ManagedNotification`
|
|
| Classes
|
|
| Indicates a JMX notification emitted by a managed resource.
|
|
|
|
| `@ManagedAttribute`
|
|
| Methods (only getters and setters)
|
|
| Marks a getter or setter as one half of a JMX attribute.
|
|
|
|
| `@ManagedMetric`
|
|
| Methods (only getters)
|
|
| Marks a getter as a JMX attribute, with added descriptor properties to indicate that it is a metric.
|
|
|
|
| `@ManagedOperation`
|
|
| Methods
|
|
| Marks a method as a JMX operation.
|
|
|
|
| `@ManagedOperationParameter`
|
|
| Methods
|
|
| Defines a description for an operation parameter.
|
|
|===
|
|
|
|
The following table describes some of the common attributes that are available for use in
|
|
these annotations. Consult the Javadoc for each annotation for further details.
|
|
|
|
[[jmx-metadata-parameters]]
|
|
.Spring JMX annotation attributes
|
|
[cols="1,1,3"]
|
|
|===
|
|
| Attribute | Applies to | Description
|
|
|
|
| `objectName`
|
|
| `@ManagedResource`
|
|
| Used by `MetadataNamingStrategy` to determine the `ObjectName` of a managed resource.
|
|
|
|
| `description`
|
|
| `@ManagedResource`, `@ManagedNotification`, `@ManagedAttribute`, `@ManagedMetric`,
|
|
`@ManagedOperation`, `@ManagedOperationParameter`
|
|
| Sets the description of the resource, notification, attribute, metric, or operation.
|
|
|
|
| `currencyTimeLimit`
|
|
| `@ManagedResource`, `@ManagedAttribute`, `@ManagedMetric`
|
|
| Sets the value of the `currencyTimeLimit` descriptor field.
|
|
|
|
| `defaultValue`
|
|
| `@ManagedAttribute`
|
|
| Sets the value of the `defaultValue` descriptor field.
|
|
|
|
| `log`
|
|
| `@ManagedResource`
|
|
| Sets the value of the `log` descriptor field.
|
|
|
|
| `logFile`
|
|
| `@ManagedResource`
|
|
| Sets the value of the `logFile` descriptor field.
|
|
|
|
| `persistPolicy`
|
|
| `@ManagedResource`, `@ManagedMetric`
|
|
| Sets the value of the `persistPolicy` descriptor field.
|
|
|
|
| `persistPeriod`
|
|
| `@ManagedResource`, `@ManagedMetric`
|
|
| Sets the value of the `persistPeriod` descriptor field.
|
|
|
|
| `persistLocation`
|
|
| `@ManagedResource`
|
|
| Sets the value of the `persistLocation` descriptor field.
|
|
|
|
| `persistName`
|
|
| `@ManagedResource`
|
|
| Sets the value of the `persistName` descriptor field.
|
|
|
|
| `name`
|
|
| `@ManagedOperationParameter`
|
|
| Sets the display name of an operation parameter.
|
|
|
|
| `index`
|
|
| `@ManagedOperationParameter`
|
|
| Sets the index of an operation parameter.
|
|
|===
|
|
|
|
|
|
[[jmx-interface-autodetect]]
|
|
== Using the `AutodetectCapableMBeanInfoAssembler` Interface
|
|
|
|
To simplify configuration even further, Spring includes the
|
|
`AutodetectCapableMBeanInfoAssembler` interface, which extends the `MBeanInfoAssembler`
|
|
interface to add support for auto-detection of MBean resources. If you configure the
|
|
`MBeanExporter` with an instance of `AutodetectCapableMBeanInfoAssembler`, it is
|
|
allowed to "vote" on the inclusion of beans for exposure to JMX.
|
|
|
|
The only implementation of the `AutodetectCapableMBeanInfo` interface is
|
|
the `MetadataMBeanInfoAssembler`, which votes to include any bean that is marked
|
|
with the `ManagedResource` attribute. The default approach in this case is to use the
|
|
bean name as the `ObjectName`, which results in configuration similar to the following:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes"]
|
|
----
|
|
<beans>
|
|
|
|
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
|
|
<!-- notice how no 'beans' are explicitly configured here -->
|
|
<property name="autodetect" value="true"/>
|
|
<property name="assembler" ref="assembler"/>
|
|
</bean>
|
|
|
|
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
|
|
<property name="attributeSource">
|
|
<bean class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
|
|
</property>
|
|
</bean>
|
|
|
|
<bean id="testBean" class="org.springframework.jmx.AnnotationTestBean">
|
|
<property name="name" value="TEST"/>
|
|
<property name="age" value="100"/>
|
|
</bean>
|
|
|
|
</beans>
|
|
----
|
|
|
|
Notice that, in the preceding configuration, no beans are passed to the `MBeanExporter`.
|
|
However, the `AnnotationTestBean` is still registered, since it is annotated with
|
|
`@ManagedResource` and the `MetadataMBeanInfoAssembler` detects this and votes to include
|
|
it. The only downside with this approach is that the name of the `AnnotationTestBean` now
|
|
has business meaning. You can address this issue by configuring an `ObjectNamingStrategy`
|
|
as explained in xref:integration/jmx/naming.adoc[Controlling `ObjectName` Instances for
|
|
Your Beans]. You can also see an example which uses the `MetadataNamingStrategy` in
|
|
xref:integration/jmx/interface.adoc#jmx-interface-metadata[Using Source-level Metadata: Java Annotations].
|
|
|
|
|
|
|
|
[[jmx-interface-java]]
|
|
== Defining Management Interfaces by Using Java Interfaces
|
|
|
|
In addition to the `MetadataMBeanInfoAssembler`, Spring also includes the
|
|
`InterfaceBasedMBeanInfoAssembler`, which lets you constrain the methods and
|
|
properties that are exposed based on the set of methods defined in a collection of
|
|
interfaces.
|
|
|
|
Although the standard mechanism for exposing MBeans is to use interfaces and a simple
|
|
naming scheme, `InterfaceBasedMBeanInfoAssembler` extends this functionality by
|
|
removing the need for naming conventions, letting you use more than one interface
|
|
and removing the need for your beans to implement the MBean interfaces.
|
|
|
|
Consider the following interface, which is used to define a management interface for the
|
|
`JmxTestBean` class that we showed earlier:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes"]
|
|
----
|
|
public interface IJmxTestBean {
|
|
|
|
public int add(int x, int y);
|
|
|
|
public long myOperation();
|
|
|
|
public int getAge();
|
|
|
|
public void setAge(int age);
|
|
|
|
public void setName(String name);
|
|
|
|
public String getName();
|
|
|
|
}
|
|
----
|
|
|
|
This interface defines the methods and properties that are exposed as operations and
|
|
attributes on the JMX MBean. The following code shows how to configure Spring JMX to use
|
|
this interface as the definition for the management interface:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes"]
|
|
----
|
|
<beans>
|
|
|
|
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
|
|
<property name="beans">
|
|
<map>
|
|
<entry key="bean:name=testBean5" value-ref="testBean"/>
|
|
</map>
|
|
</property>
|
|
<property name="assembler">
|
|
<bean class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
|
|
<property name="managedInterfaces">
|
|
<value>org.springframework.jmx.IJmxTestBean</value>
|
|
</property>
|
|
</bean>
|
|
</property>
|
|
</bean>
|
|
|
|
<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
|
|
<property name="name" value="TEST"/>
|
|
<property name="age" value="100"/>
|
|
</bean>
|
|
|
|
</beans>
|
|
----
|
|
|
|
In the preceding example, the `InterfaceBasedMBeanInfoAssembler` is configured to use the
|
|
`IJmxTestBean` interface when constructing the management interface for any bean. It is
|
|
important to understand that beans processed by the `InterfaceBasedMBeanInfoAssembler`
|
|
are not required to implement the interface used to generate the JMX management
|
|
interface.
|
|
|
|
In the preceding case, the `IJmxTestBean` interface is used to construct all management
|
|
interfaces for all beans. In many cases, this is not the desired behavior, and you may
|
|
want to use different interfaces for different beans. In this case, you can pass
|
|
`InterfaceBasedMBeanInfoAssembler` a `Properties` instance through the `interfaceMappings`
|
|
property, where the key of each entry is the bean name and the value of each entry is a
|
|
comma-separated list of interface names to use for that bean.
|
|
|
|
If no management interface is specified through either the `managedInterfaces` or
|
|
`interfaceMappings` properties, the `InterfaceBasedMBeanInfoAssembler` reflects
|
|
on the bean and uses all of the interfaces implemented by that bean to create the
|
|
management interface.
|
|
|
|
|
|
[[jmx-interface-methodnames]]
|
|
== Using `MethodNameBasedMBeanInfoAssembler`
|
|
|
|
`MethodNameBasedMBeanInfoAssembler` lets you specify a list of method names
|
|
that are exposed to JMX as attributes and operations. The following code shows a sample
|
|
configuration:
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes"]
|
|
----
|
|
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
|
|
<property name="beans">
|
|
<map>
|
|
<entry key="bean:name=testBean5" value-ref="testBean"/>
|
|
</map>
|
|
</property>
|
|
<property name="assembler">
|
|
<bean class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler">
|
|
<property name="managedMethods">
|
|
<value>add,myOperation,getName,setName,getAge</value>
|
|
</property>
|
|
</bean>
|
|
</property>
|
|
</bean>
|
|
----
|
|
|
|
In the preceding example, you can see that the `add` and `myOperation` methods are exposed as JMX
|
|
operations, and `getName()`, `setName(String)`, and `getAge()` are exposed as the
|
|
appropriate half of a JMX attribute. In the preceding code, the method mappings apply to
|
|
beans that are exposed to JMX. To control method exposure on a bean-by-bean basis, you can use
|
|
the `methodMappings` property of `MethodNameMBeanInfoAssembler` to map bean names to
|
|
lists of method names.
|
|
|
|
|
|
|