4.2.5.1. Создание JMX-бина
Рассмотрим процесс создания JMX-бина на примере.
-  
Интерфейс JMX-бина:
package com.sample.sales.core; import org.springframework.jmx.export.annotation.*; @ManagedResource(description = "Performs operations on Orders") public interface OrdersMBean { @ManagedOperation(description = "Recalculates an order amount") @ManagedOperationParameters({@ManagedOperationParameter(name = "orderId", description = "")}) String calculateTotals(String orderId); }Интерфейс и его методы могут содержать аннотации для задания описания JMX-бина и его операций. Это описание будет отображаться во всех инструментах, работающих с данным JMX-интерфейсом, тем самым помогая администратору системы.
Так как инструменты JMX поддерживают ограниченный набор типов данных, параметры и результат метода желательно задавать типа
String, и при необходимости выполнять конвертацию внутри метода. -  
Класс JMX-бина:
package com.sample.sales.core; import com.haulmont.cuba.core.*; import com.haulmont.cuba.core.app.*; import com.sample.sales.entity.Order; import org.apache.commons.lang.exception.ExceptionUtils; import org.springframework.stereotype.Component; import javax.inject.Inject; import java.util.UUID; @Component("sales_OrdersMBean") public class Orders implements OrdersMBean { @Inject protected OrderWorker orderWorker; @Inject protected Persistence persistence; @Authenticated @Override public String calculateTotals(String orderId) { try { try (Transaction tx = persistence.createTransaction()) { Order entity = persistence.getEntityManager().find(Order.class, UUID.fromString(orderId)); orderWorker.calculateTotals(entity); tx.commit(); }; return "Done"; } catch (Throwable e) { return ExceptionUtils.getStackTrace(e); } } }Аннотация
@Componentопределяет, что данный класс является управляемым бином с именемsales_OrdersMBean. Имя указано напрямую в аннотации, а не в константе, так как доступ к JMX-бину из кода Java не требуется.Рассмотрим реализацию метода
calculateTotals().-  
Метод имеет аннотацию
@Authenticated, т.е. при входе в метод и при отсутствии в потоке выполнения пользовательской сессии выполняется системная аутентификация. -  
Тело метода обернуто в блок try/catch, так что метод в случае успешного выполнения возвращает строку "Done", а в случае ошибки - stacktrace исключения в виде строки.
В данном случае все исключения обрабатываются, а значит, не попадают в
MBeanInterceptorи не выводятся в журнал автоматически. Поэтому при необходимости логгировать исключения здесь нужно добавить вызов логгера в секцииcatch. -  
Логика метода заключается в том, что он стартует транзакцию, загружает экземпляр сущности
Orderпо идентификатору и передает управление бинуOrderWorkerдля обработки. 
 -  
 -  
Регистрация JMX-бина в
spring.xml:<bean id="sales_MBeanExporter" lazy-init="false" class="com.haulmont.cuba.core.sys.jmx.MBeanExporter"> <property name="beans"> <map> <entry key="${cuba.webContextName}.sales:type=Orders" value-ref="sales_OrdersMBean"/> </map> </property> </bean> 
Все JMX-бины проекта объявляются в одном экземпляре MBeanExporter в элементах map/entry свойства beans. Ключом элемента здесь является JMX ObjectName, значением - имя бина, заданное в аннотации @Component. ObjectName начинается с имени веб-приложения, так как в одном экземпляре сервера приложения (т.е. в одной JVM) может быть развернуто несколько веб-приложений, экспортирующих одинаковые JMX-интерфейсы.