You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
417 lines
15 KiB
417 lines
15 KiB
[[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` Interface |
|
|
|
Behind the scenes, the `MBeanExporter` delegates to an implementation of the |
|
`org.springframework.jmx.export.assembler.MBeanInfoAssembler` interface, 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 (there is no default). |
|
|
|
To mark a bean for export to JMX, you should annotate the bean class with the |
|
`ManagedResource` annotation. You must mark each method you wish to expose as an operation |
|
with the `ManagedOperation` annotation and mark each property you wish to expose |
|
with the `ManagedAttribute` annotation. When marking 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 |
|
an operation or an attribute. |
|
|
|
The following example shows the 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; |
|
|
|
import org.springframework.jmx.export.annotation.ManagedResource; |
|
import org.springframework.jmx.export.annotation.ManagedOperation; |
|
import org.springframework.jmx.export.annotation.ManagedAttribute; |
|
|
|
@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 implements IJmxTestBean { |
|
|
|
private String name; |
|
private int age; |
|
|
|
@ManagedAttribute(description="The Age Attribute", currencyTimeLimit=15) |
|
public int getAge() { |
|
return age; |
|
} |
|
|
|
public void setAge(int age) { |
|
this.age = 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 name; |
|
} |
|
|
|
@ManagedOperation(description="Add two numbers") |
|
@ManagedOperationParameters({ |
|
@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 `JmxTestBean` class is marked with the |
|
`ManagedResource` annotation and that this `ManagedResource` annotation is configured |
|
with a set of properties. These properties 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[Source-level Metadata Types]. |
|
|
|
Both the `age` and `name` properties are annotated with the `ManagedAttribute` |
|
annotation, but, in the case of the `age` property, only the getter is marked. |
|
This causes both of these properties to be included in the management interface |
|
as attributes, but the `age` attribute is read-only. |
|
|
|
Finally, the `add(int, int)` method is marked with the `ManagedOperation` attribute, |
|
whereas the `dontExposeMe()` method is not. This causes the management interface to |
|
contain only one operation (`add(int, int)`) when you use the `MetadataMBeanInfoAssembler`. |
|
|
|
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> |
|
|
|
<bean id="jmxAttributeSource" |
|
class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/> |
|
|
|
<!-- 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="testBean" class="org.springframework.jmx.AnnotationTestBean"> |
|
<property name="name" value="TEST"/> |
|
<property name="age" value="100"/> |
|
</bean> |
|
</beans> |
|
---- |
|
|
|
In the preceding example, an `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 |
|
metadata-driven management interfaces for your Spring-exposed MBeans. |
|
|
|
|
|
[[jmx-interface-metadata-types]] |
|
== Source-level Metadata Types |
|
|
|
The following table describes the source-level metadata types that are available for use in Spring JMX: |
|
|
|
[[jmx-metadata-types]] |
|
.Source-level metadata types |
|
|=== |
|
| Purpose| Annotation| Annotation Type |
|
|
|
| Mark all instances of a `Class` as JMX managed resources. |
|
| `@ManagedResource` |
|
| Class |
|
|
|
| Mark a method as a JMX operation. |
|
| `@ManagedOperation` |
|
| Method |
|
|
|
| Mark a getter or setter as one half of a JMX attribute. |
|
| `@ManagedAttribute` |
|
| Method (only getters and setters) |
|
|
|
| Define descriptions for operation parameters. |
|
| `@ManagedOperationParameter` and `@ManagedOperationParameters` |
|
| Method |
|
|=== |
|
|
|
The following table describes the configuration parameters that are available for use on these source-level |
|
metadata types: |
|
|
|
[[jmx-metadata-parameters]] |
|
.Source-level metadata parameters |
|
[cols="1,3,1"] |
|
|=== |
|
| Parameter | Description | Applies to |
|
|
|
| `ObjectName` |
|
| Used by `MetadataNamingStrategy` to determine the `ObjectName` of a managed resource. |
|
| `ManagedResource` |
|
|
|
| `description` |
|
| Sets the friendly description of the resource, attribute or operation. |
|
| `ManagedResource`, `ManagedAttribute`, `ManagedOperation`, or `ManagedOperationParameter` |
|
|
|
| `currencyTimeLimit` |
|
| Sets the value of the `currencyTimeLimit` descriptor field. |
|
| `ManagedResource` or `ManagedAttribute` |
|
|
|
| `defaultValue` |
|
| Sets the value of the `defaultValue` descriptor field. |
|
| `ManagedAttribute` |
|
|
|
| `log` |
|
| Sets the value of the `log` descriptor field. |
|
| `ManagedResource` |
|
|
|
| `logFile` |
|
| Sets the value of the `logFile` descriptor field. |
|
| `ManagedResource` |
|
|
|
| `persistPolicy` |
|
| Sets the value of the `persistPolicy` descriptor field. |
|
| `ManagedResource` |
|
|
|
| `persistPeriod` |
|
| Sets the value of the `persistPeriod` descriptor field. |
|
| `ManagedResource` |
|
|
|
| `persistLocation` |
|
| Sets the value of the `persistLocation` descriptor field. |
|
| `ManagedResource` |
|
|
|
| `persistName` |
|
| Sets the value of the `persistName` descriptor field. |
|
| `ManagedResource` |
|
|
|
| `name` |
|
| Sets the display name of an operation parameter. |
|
| `ManagedOperationParameter` |
|
|
|
| `index` |
|
| Sets the index of an operation parameter. |
|
| `ManagedOperationParameter` |
|
|=== |
|
|
|
|
|
[[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 autodetection 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 a 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="testBean" class="org.springframework.jmx.JmxTestBean"> |
|
<property name="name" value="TEST"/> |
|
<property name="age" value="100"/> |
|
</bean> |
|
|
|
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler"> |
|
<property name="attributeSource"> |
|
<bean class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/> |
|
</property> |
|
</bean> |
|
|
|
</beans> |
|
---- |
|
|
|
Notice that, in the preceding configuration, no beans are passed to the `MBeanExporter`. |
|
However, the `JmxTestBean` is still registered, since it is marked with the `ManagedResource` |
|
attribute and the `MetadataMBeanInfoAssembler` detects this and votes to include it. |
|
The only problem with this approach is that the name of the `JmxTestBean` now has business |
|
meaning. You can address this issue by changing the default behavior for `ObjectName` |
|
creation as defined in xref:integration/jmx/naming.adoc[Controlling `ObjectName` Instances for Your Beans]. |
|
|
|
|
|
[[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. |
|
|
|
|
|
|
|
|