3.2.5.1. 创建 JMX Bean
以下示例展示如何创建 JMX Bean。
-
JMX bean 接口:
package com.sample.sales.core; import org.springframework.jmx.export.annotation.*; import com.haulmont.cuba.core.sys.jmx.JmxBean; @JmxBean(module = "sales", alias = "OrdersMBean") @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 Bean 和它提供的操作进行描述。这些描述会显示在使用 JMX 接口的所有工具中,这样可以帮助系统管理员了解接口。
-
可选的
@JmxBean
注解用来自动注册类实例至 JMX 服务,按照module
和alias
属性来注册。可以使用这个注解来注册 JMX bean,代替在 spring.xml 中配置。 -
可选的
@JmxRunAsync
注解用来标识出一个需要长时间执行的操作。当使用内置的 JMX console 运行此操作时,平台将会显示一个带有无限进度条和 Cancel 按钮的对话框。用户可以中断操作并继续使用应用程序。该注解还可以包含timeout
参数,该参数用来设置操作的最长执行时间(以毫秒为单位),例如:@JmxRunAsync(timeout = 30000) String calculateTotals();
如果执行超时,对话框将关闭并显示错误消息。
请注意,如果在用户界面上取消操作,或者观察到操作超时,但操作实际上继续在后台运行,也就是说这些操作不能实际终止,只是将控制权交给用户。
-
由于 JMX 工具只支持有限的数据类型,因此最好使用
String
作为方法的参数和结果类型,必要时,需要在方法内进行类型转换。除了String
外,还支持以下参数类型:boolean
、double
、float
、int
、long
、Boolean
、Integer
。
-
-
JMX bean 类:
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
名称的 Spring bean,该名称直接在注解中指定而不是在常量中,因为不需要从 Java 代码访问 JMX bean。下面概述一下
calculateTotals()
方法的实现。 -
在
spring.xml
中注册 JMX bean:<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 beans 都是在
beans
属性的map/entry
元素中的一个MBeanExporter
实例中声明的。键是 JMX ObjectName,值是在@Component
注解中指定的 bean 名称。ObjectName 以 web 应用程序的名称开始,因为可以将输出相同 JMX 接口的多个 web 应用程序部署到一个应用程序服务实例中(部署到 JVM 中)。