"За кулисами" MBeanExporter делегирует свои полномочия реализации ObjectNamingStrategy для получения экземпляра ObjectName для каждого из бинов, которые он регистрирует. По умолчанию, стандартная реализация, KeyNamingStrategy, использует ключ beans Map в качестве ObjectName. Кроме того, KeyNamingStrategy может отображать ключ beans Map на запись в файле Properties (или файлах) для разрешения ObjectName. В дополнение к KeyNamingStrategy, Spring предусматривает две дополнительные реализации ObjectNamingStrategy: IdentityNamingStrategy (которая компонует ObjectName на основе JVM-идентификатора бина) и MetadataNamingStrategy (которая использует метаданные на уровне источника для получения ObjectName).

Чтение экземпляров ObjectName из свойств

Можно сконфигурировать свой собственный экземпляр KeyNamingStrategy и настроить его на чтение экземпляров ObjectName из экземпляра Properties вместо использования ключа бина. KeyNamingStrategy будет пытаться найти запись в Properties с ключом, который соответствует ключу бина. Если запись не будет найдена или если экземпляр Properties равен null, используется сам ключ бина.

В следующем коде продемонстрирован пример конфигурации для KeyNamingStrategy:

<beans>
    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
        <property name="beans">
            <map>
                <entry key="testBean" value-ref="testBean"/>
            </map>
        </property>
        <property name="namingStrategy" ref="namingStrategy"/>
    </bean>
    <bean id="testBean" class="org.springframework.jmx.JmxTestBean">
        <property name="name" value="TEST"/>
        <property name="age" value="100"/>
    </bean>
    <bean id="namingStrategy" class="org.springframework.jmx.export.naming.KeyNamingStrategy">
        <property name="mappings">
            <props>
                <prop key="testBean">bean:name=testBean1</prop>
            </props>
        </property>
        <property name="mappingLocations">
            <value>names1.properties,names2.properties</value>
        </property>
    </bean>
</beans>

В предыдущем примере экземпляр KeyNamingStrategy конфигурируется с экземпляром Properties, который объединен из экземпляра Properties, определенного свойством отображения, и файлов свойств, расположенных в путях, определенных свойством отображений. В этой конфигурации бину testBean присвоено ObjectName вида bean:name=testBean1, поскольку именно эта запись в экземпляре Properties имеет ключ, соответствующий ключу этого бина.

Если запись в экземпляре Properties не найдена, имя ключа бина используется в качестве ObjectName.

Использование MetadataNamingStrategy

MetadataNamingStrategy использует свойство objectName атрибута ManagedResource каждого бина для создания ObjectName. В следующем коде продемонстрирована конфигурация для MetadataNamingStrategy:

<beans>
    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
        <property name="beans">
            <map>
                <entry key="testBean" value-ref="testBean"/>
            </map>
        </property>
        <property name="namingStrategy" ref="namingStrategy"/>
    </bean>
    <bean id="testBean" class="org.springframework.jmx.JmxTestBean">
        <property name="name" value="TEST"/>
        <property name="age" value="100"/>
    </bean>
    <bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
        <property name="attributeSource" ref="attributeSource"/>
    </bean>
    <bean id="attributeSource"
            class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
</beans>

Если для атрибута ManagedResource не было указано objectName, создается ObjectName в таком формате: [fully-qualified-package-name]:type=[short-classname],name=[bean-name]. Например, сгенерированное ObjectName для следующего бина будет com.example:type=MyClass,name=myBean:

<bean id="myBean" class="com.example.MyClass"/>

Настройка экспорта бинов MBean на основе аннотаций

Если вы предпочитаете использовать подход, основанный на аннотациях, для определения интерфейсов управления, то вам доступен вспомогательный подкласс MBeanExporter: AnnotationMBeanExporter. При определении экземпляра этого подкласса больше не требуются конфигурации namingStrategy, assembler и attributeSource, поскольку он всегда использует стандартные метаданные на основе Java-аннотаций (автоматическое обнаружение также всегда активировано). На самом деле, вместо определения бина MBeanExporter, можно использовать еще более простой синтаксис, поддерживаемый аннотацией @EnableMBeanExport @Configuration, как это показано в следующем примере:

@Configuration
@EnableMBeanExport
public class AppConfig {
}

Если вы предпочитаете конфигурацию на основе XML, элемент <context:mbean-export/> служит той же цели и продемонстрирован в следующем листинге:

<context:mbean-export/>

При необходимости можно предоставить ссылку на конкретный server для MBean, а атрибут defaultDomain (свойство AnnotationMBeanExporter) будет принимать альтернативное значение для сгенерированных доменов ObjectName для MBean. Это имя используется вместо полного имени пакета, что и показано в следующем примере:

@EnableMBeanExport(server="myMBeanServer", defaultDomain="myDomain")
@Configuration
ContextConfiguration {
}

Следующий пример демонстрирует XML-эквивалент предыдущего примера, основанного на аннотации:

<context:mbean-export server="myMBeanServer" default-domain="myDomain"/>
Не используйте основанные на интерфейсе прокси АОП в сочетании с автоматическим обнаружением JMX-аннотаций в классах бинов. Прокси на основе интерфейса "скрывают" целевой класс, который также скрывает аннотации ресурсов, управляемых JMX. Следовательно, в этом случае следует использовать прокси целевого класса (через установку флага "proxy-target-class" в <aop:config/>, <tx:annotation-driven/> и так далее). В противном случае JMX-бины могут быть молча проигнорированы при запуске.