В примере из предыдущего раздела контроль над интерфейсом управления бина осуществлялся в малой степени. Все публичные свойства и методы каждого экспортируемого бина были открыты как атрибуты и операции JMX, соответственно. Для осуществления более тонкого контроля над тем, какие именно свойства и методы экспортируемых вами бинов на самом деле открыты как атрибуты и операции JMX, средства поддержки Spring для JMX предусматривают комплексный и расширяемый механизм контроля над интерфейсами управления бинами.
Использование интерфейса MBeanInfoAssembler
"За кулисами" MBeanExporter
делегирует свои полномочия реализации интерфейса org.springframework.jmx.export.assembler.MBeanInfoAssembler
, который отвечает за определение интерфейса управления каждого экспортируемого бина. Реализация по умолчанию, org.springframework.jmx.export.assembler.SimpleReflectiveMBeanInfoAssembler
, определяет интерфейс управления, который открывает все публичные свойства и методы (как видно из примеров в предыдущих разделах). Spring предоставляет две дополнительные реализации интерфейса MBeanInfoAssembler
, которые позволяют контролировать сгенерированный интерфейс управления, используя либо метаданные на уровне источника, либо произвольный интерфейс.
Использование метаданных на уровне источника: Java-аннотации
Используя MetadataMBeanInfoAssembler
, можно определять интерфейсы управления для ваших бинов, используя метаданные на уровне источника. Чтение метаданных инкапсулируется интерфейсом org.springframework.jmx.export.metadata.JmxAttributeSource
. Фреймворк JMX в Spring предусматривает реализацию по умолчанию, которая использует Java-аннотации, а именно org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource
. Для корректной работы MetadataMBeanInfoAssembler
необходимо сконфигурировать экземпляр реализации интерфейса JmxAttributeSource
(по умолчанию он отсутствует).
Чтобы пометить бин для экспорта в JMX, необходимо аннотировать класс бина аннотацией ManagedResource
. Нужно помечать каждый метод, который необходимо открыть как операцию, аннотацией ManagedOperation
, а также помечать ManagedAttribute
каждое свойство, которое необходимо открыть. Помечая свойства, можно опустить аннотацию геттера или сеттера, чтобы создать атрибут "только для записи" или "только для чтения", соответственно.
ManagedResource
бин должен быть публичным, как и методы, открывающие операцию или атрибут.В следующем примере показана аннотированная версия класса JmxTestBean
:
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();
}
}
Из предыдущего примера видно, что класс JmxTestBean
помечен аннотацией ManagedResource
и что эта аннотация ManagedResource
сконфигурирована с набором свойств. Эти свойства могут быть использованы для настройки различных аспектов MBean, который генерируется MBeanExporter
, и более подробно описаны далее.
Оба свойства – age
и name
– помечены аннотацией ManagedAttribute
, но в случае свойства age
помечен только геттер. В результате оба эти свойства будут включены в интерфейс управления как атрибуты, но атрибут age
будет доступен только для чтения.
Наконец, метод add(int, int)
помечен атрибутом ManagedOperation
, а метод dontExposeMe()
– нет. Это приводит к тому, что интерфейс управления содержит только одну операцию (add(int, int)
) при использовании MetadataMBeanInfoAssembler
.
Следующая конфигурация показывает, как можно настроить MBeanExporter
на использование MetadataMBeanInfoAssembler
:
<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"/>
<!-- создаст интерфейс управления, используя метаданные аннотации -->
<bean id="assembler"
class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource" ref="jmxAttributeSource"/>
</bean>
<!-- перехватит имя объекта из аннотации -->
<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>
В предыдущем примере бин MetadataMBeanInfoAssembler
был сконфигурирован с экземпляром класса AnnotationJmxAttributeSource
и передан MBeanExporter
через свойство ассемблера. Это все, что требуется для использования преимуществ интерфейсов управления на основе метаданных для ваших бинов MBean, переданных в Spring.
Типы метаданных на уровне источника
В следующей таблице описаны типы метаданных на уровне источника, которые доступны для использования в JMX через Spring:
Назначение | @annotation: | Тип аннотации |
---|---|---|
Помечает все экземпляры |
|
Класс |
Помечает метод как JMX-операцию. |
|
Метод |
Помечает геттер или сеттер как одну половину JMX-атрибута. |
|
Метод (только геттеры и сеттеры) |
Определяет описания для параметров операции. |
|
Метод |
В следующей таблице описаны параметры конфигурации, доступные для использования в этих типах метаданных на уровне источника:
Параметр | Описание | Применимо к |
---|---|---|
|
Используется |
|
|
Устанавливает удобное для использования описание ресурса, атрибута или операции. |
|
|
Устанавливает значение поля дескриптора |
|
|
Устанавливает значение поля дескриптора |
|
|
Устанавливает значение поля дескриптора |
|
|
Устанавливает значение поля дескриптора |
|
|
Устанавливает значение поля дескриптора |
|
|
Устанавливает значение поля дескриптора |
|
|
Устанавливает значение поля дескриптора |
|
|
Устанавливает значение поля дескриптора |
|
|
Устанавливает отображаемое имя параметра операции. |
|
|
Устанавливает индекс параметра операции. |
|
Использование интерфейса AutodetectCapableMBeanInfoAssembler
Чтобы еще больше упростить конфигурирование, Spring предусматривает интерфейс AutodetectCapableMBeanInfoAssembler
, который расширяет интерфейс MBeanInfoAssembler
для добавления средств поддержки автоматического определения MBean-ресурсов. Если сконфигурировать MBeanExporter
с экземпляром AutodetectCapableMBeanInfoAssembler
, ему будет разрешено "голосовать" за то, чтобы бины были включены в список для открытия в JMX.
Единственной реализацией интерфейса AutodetectCapableMBeanInfo
является MetadataMBeanInfoAssembler
, который голосует за включение любого бина, помеченного атрибутом ManagedResource
. По умолчанию в этом случае в качестве ObjectName
используется имя бина, что приводит нас к конфигурации, подобной следующей:
<beans>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<!-- обратите внимание, что здесь нет явной конфигурации "бинов" -->
<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>
Обратите внимание, что в предыдущей конфигурации MBeanExporter
никакие бины не передаются. Однако JmxTestBean
все еще зарегистрирован, поскольку он помечен атрибутом ManagedResource
, это обнаруживает MetadataMBeanInfoAssembler
и голосует за включение этого бина. Единственная проблема данного подхода заключается в том, что имя JmxTestBean
теперь имеет бизнес-значение. Эту проблему можно решить, изменив логику поведения по умолчанию для создания ObjectName
.
Определение интерфейсов управления с помощью интерфейсов Javas
В дополнение к MetadataMBeanInfoAssembler
, Spring также содержит InterfaceBasedMBeanInfoAssembler
, который позволяет ограничивать методы и свойства, которые открыты на основе набора методов, определенных в коллекции интерфейсов.
Хотя стандартным механизмом для открытия MBeans является использование интерфейсов и простой схемы назначения имен, InterfaceBasedMBeanInfoAssembler
расширяет эту функциональность, устраняя необходимость в соглашениях об именовании, позволяя использовать более одного интерфейса и устраняя необходимость для бинов реализовывать MBean-интерфейсы.
Рассмотрим следующий интерфейс, который используется для определения интерфейса управления для класса JmxTestBean
, который мы показали ранее:
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();
}
Этот интерфейс определяет методы и свойства, открытые в качестве операций и атрибутов JMX MBean. Следующий код показывает, как сконфигурировать JMX в Spring на использование этого интерфейса в качестве определения для интерфейса управления:
<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>
В предыдущем примере InterfaceBasedMBeanInfoAssembler
сконфигурирован на использование интерфейса IJmxTestBean
при построении интерфейса управления для любого бина. Важно понимать, что бины, обрабатываемые InterfaceBasedMBeanInfoAssembler
, не обязательно должны реализовывать интерфейс, используемый для генерации интерфейса управления JMX.
В предыдущем случае интерфейс IJmxTestBean
используется для построения всех интерфейсов управления для всех бинов. Во многих случаях такая логика работы не является желаемой, поэтому может возникнуть желание использовать разные интерфейсы для разных бинов. В этом случае можно передать интерфейсу InterfaceBasedMBeanInfoAssembler
экземпляр Properties
через свойство interfaceMappings
, где ключом каждой записи является имя бина, а значением каждой записи – разделенный запятыми список имен интерфейсов, которые следует использовать для этого бина.
Если интерфейс управления не задан через свойства managedInterfaces
или interfaceMappings
, интерфейс InterfaceBasedMBeanInfoAssembler
отражает бин и использует все интерфейсы, реализованные этим бином, для создания интерфейса управления.
Использование MethodNameBasedMBeanInfoAssembler
MethodNameBasedMBeanInfoAssembler
позволяет задать список имен методов, которые открыты для JMX как атрибуты и операции. В следующем коде показан пример конфигурации:
<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>
Из предыдущего примера понятно, что методы add
и myOperation
открыты как JMX-операции, а getName()
, setName(String)
и getAge()
открыты как соответствующие половины JMX-атрибутов. В предыдущем коде отображения методов применяются к бинам, которые открыты для JMX. Чтобы управлять воздействием методов на каждый бин, можно использовать methodMappings
свойства MethodNameMBeanInfoAssembler
для отображения имен бинов на списки имен методов.