20.2.2 访问远程 MBean

要想访问远程 MBean 服务器,我们需要在 Spring上下文中配置 MbeanServerConnectionFactoryBean。下面的 bean 声明装配了一个 MbeanServerConnectionFactoryBean,该 bean 用于访问我们在上一节中所创建的基于 RMI 的远程服务器。

@Bean
public MBeanServerConnectionFactoryBean connectionFactoryBean() {
  MBeanServerConnectionFactoryBean mbscfb = new MBeanServerConnectionFactoryBean();
  mbscfb.setServiceUrl("service:jinx:rmi://localhost/jndi/rmi://localhost:1099/spitter");
  return mbscfb;
}

顾名思义,MBeanServerConnectionFactoryBean 是一个可用于创建 MbeanServerConnection 的工厂 bean。由 MBeanServerConnectionFactoryBean 所生成的 MBeanServerConnection 实际上是作为远程 MBean 服务器的本地代理。它能够以 MBeanServerConnection 的形式注入到其他 bean 的属性中:

@Bean
public JmxClient jmxClient(MBeanServerConnection connection) {
  JmxClient jmxClient = new JmxClient();
  jmxClient.setMbeanServerConnection(connection);
  return jmxClient;
}

MBeanServerConnection 提供了多种方法,我们可以使用这些方法查询远程 MBean 服务器并调用 MBean 服务器内所注册的 MBean 的方法。例如,如果我们希望知道在远程MBean服务器中有多少已注册的 MBean,可以用如下的代码片段打印这些信息:

int mbeanCount = mbeanServerConnection.getMBeanCount();
System.out.println("There are " + mbeanCount + " MBeans");

我们还可以使用 queryNames() 方法查询远程服务器中所有 MBean 的名称:

java.util.Set mbeanNames = mbeanServerConnection.queryNames(null, null);

传递给 queryNames() 方法的两个参数用于过滤查询结果。如果将两个参数都设置为 null,输出结果为所有已注册的 MBean 的名称。

查询远程 MBean 服务器上 bean 的数量和名称虽然很有趣,不过并不能完成更多的工作。远程访问 MBean 服务器的真正价值在于访问远程服务器上已注册 MBean 的属性以及调用它们的方法。

为了访问 MBean 属性,我们可以使用 getAttribute() 和 setAttribute() 方法。例如,为了获取 MBean 属性的值,我们可以按照下面的方法调用 getAttribute() 方法:

String cronExpression = mbeanServerConnection.getAttribute(
  new ObjectName("spitter:name=SpittleController"), "spittlesPerPage");

同样,我们可以使用 setAttribute() 方法改变 MBean 属性的值:

mbeanServerConnection.setAttribute(
  new ObjectName("spitter:name=SpittleController"),
  new Attribute("spittlesPerPage", 10));

如果希望调用 MBean 的操作,那我们需要使用 invoke() 方法。下面的内容描述了如何调用 SpittleController MBean 的 setSpittlesPerPage() 方法:

mbeanServerConnection.invoke(
  new ObjectName("spitter:name=SpittleController"),
  "spittlesPerPage",
  new Object[] { 100 },
  new String[] { "int" });

我们还可以使用 MBeanServerConnection 的方法对远程 MBean 做很多其他的事情。我把它作为一个任务留给你。不过,通过 MBeanServerConnection 对远程 MBean 进行方法调用和属性设置是一种很笨拙的方法。要想调用 setSpittlesPerPage() 这样一个简单的方法,我们需要创建一个 ObjectName 实例,并向 invoke() 方法传递几个参数。它并不是直观的方法调用。为了更直接地调用方法,我们需要代理远程 MBean。

Last updated