JBoss
服务器是建立在
JBoss
的
JMX
实现工具(
JBossMX
)基础上的,访问
JBoss
网站(
http://www.jboss.org
)可以下载到独立的
JBoss JMX
实现工具软件包
。将下载到的
jbossmx-1.1.2.zip
压缩包解压之后,把下列
jar
文件添加到
CLASSPATH
中:
jbossmx-1.1.2/jbossmx-1.1.2/lib/jboss-jmx.jar
jbossmx-1.1.2/jbossmx-1.1.2/lib/jboss-jmx-core.jar
JBOSS_HOME/client/gnu-regexp.jar
JBOSS_HOME/client/jbossall-client.jar
标准
MBean
在
JBoss
中使用范围最广,
JBoss
中的许多组件都是利用标准
MBean
开发的。
1
.计数器
MBean
下面是一个计数器
MBean
的开发示例。
(
1
)确定
MBean
的接口。
分析计数器的功能,确定了两个方法,
即
add()
和
get()
,
add()
负责加数,
get()
负
责加数并取回总数:
package
com.liuyang.jmx.mbeans.counter;
public interface
CounterMBean {
public void add(int num);
public int get(int num);
}
(
2
)实现
MBean
接口。
CounterMBean
是一个标准
MBean
,所以
MBean
实现类的名称必须和
MBean
接口
之间遵守标准
MBean
的命名规范,所以
CounterMBean
的实现类
Counter
比
CounterMBean
少了尾部的
MBean
部分,下面是
Counter
的实现代码:
package
com.liuyang.jmx.mbeans.counter;
public
class Counter implements CounterMBean {
int
sum = 0;
public
void add(int num) {
sum+=num;
}
public
int get(int num) {
sum+=num;
return
sum;
}
}
从代码中也可以看到,标准
MBean
实现类与普通的
Java
程序也没什么区别。
(
3
)利用
JMX API
编写调用
CounterMBean
的程序。
JMX API
是
Sun
公司为
JMX
技术所设计的一套用来开发
JMX
应用的编程接口,通过
JMX API
可以管理和控制前面开发的
CounterMBean
资源。下面是利用
JMX API
编写调用
CounterMBean
的程序代码:
package
com.liuyang.jmx.mbeans.counter;
import
javax.management.MBeanServer;
import
javax.management.MBeanServerFactory;
import
javax.management.ObjectName;
public
class CounterServer {
public
static void main(String[] args) throws Exception {
MBeanServer server = MBeanServerFactory.createMBeanServer();
ObjectName name = new ObjectName("book.liuyang:service=Counter");
server.registerMBean(new Counter(), name);
String[] sig1 = {"int"};
Object[] opArgs1 = {new Integer(3)};
Object result1 = server.invoke(name, "add", opArgs1, sig1);
System.out.println(result1);
String[] sig2 = {"int"};
Object[] opArgs2 = {new Integer(0)};
Object result2 = server.invoke(name, "get", opArgs2, sig2);
System.out.println(result2);
}
}
2
.
ObjectName
ObjectName
代表一个
MBean
对象的名,创建一个
ObjectName
需要符合
MBean
的命名规范,例如:
ObjectName name = new ObjectName("book.liuyang:service=Counter");
3
.
MBeanServer
在
CounterServer
程序中,首先创建的
MBeanServer
这个对象代表前文中介绍的
MBean
服务器,它负责管理
MBean
资源,每个
MBean
资源可以被注册到
MBeanServer
之中:
server.registerMBean(new Counter(), name);
通过 MBeanServer 的 invoke 方法还可以调用一个 MBean ,在调用时需要传递一些与调用有关的参数:
Object result1 = server.invoke(name, "add", opArgs1, sig1);
其中:
name 是被调用对象的对象名。
"add" 要求 调用被调对象的方法名称。
opArgs1 是一个数组,包含着的每个数据将被作为参数传递到被调方法。
sig1
是 一个数组,包含着将被作为参数传递的每个数据的数据类型。
调用之后返回的对象包含着执行的结果。
4
.
MBeanServerFactory
MBeanServerFactory 是产生
MBeanServer 的工厂类,使用的 JMX 实现工具不同,通过
MBeanServerFactory 创建的
MBeanServer 实现对象也不同。如果
MBeanServer 已经被创建了,那么可以通过下面的方法获取:
MBeanServer server = MBeanServerFactory.newMBeanServer();
通过这个实例,可以了解到使用
MBeanServer 来控制 MBean 的基本方法,下面的 用户查询 MBean 将进一步介绍通过
MBeanServer 对 MBean 的属性进行查询的方法。
5 .用户查询 MBean
首先,确定 MBean 的接口。
用户查询 MBean
中的用户是这个
MBean
所代表的对象,这个设计的用户包括名称和角色,在这个例子中将对这两个属性进行监控,这是
JMX
为开发者提供的一种机制,所有被管理的
MBean
都在
MBeanServer
的控制之中,这个控制不仅包括上个计数器实例中所演示的方法调用功能,也包含对这些
MBean
的相关信息进行考察的功能。
package
com.liuyang.jmx.mbeans.user;
public
interface UserMBean {
public String getName();
publicvoid setName(String name);
public String getRole();
public void setRole(String string);
public String getRole();
public void setRole(String string);
}
UserMBean 中被设定了两个属性: name 和 role ,并遵照 Java Bean 的规则为它们提供了 get() 和 set() 方法。通过这两个方法可以设定 UserMBean 的两个属性。
package
com.liuyang.jmx.mbeans.user;
public
class User implements UserMBean {
private String name = "";
private String name = "";
private String password = "";
private String role = "";
private String role = "";
public String getName() {
return name;
}
publicvoid setName(String name) {
this.name = name;
}
public
String getRole() {
return
role;
}
public
void setRole(String string) {
role = string;
}
}
User 这个类只是以最简单的方式实现了 UserMBean 接口。
下 面
的
UserQueries 演示了 通过
MBeanServer 对 MBean 的属性进行查询的方法,代码如下:
package
com.liuyang.jmx.mbeans.user;
import
java.util.Iterator;
import
java.util.Set;
import
javax.management.Attribute;
import
javax.management.MBeanServer;
import
javax.management.MBeanServerFactory;
import
javax.management.ObjectName;
import
javax.management.Query;
import
javax.management.QueryExp;
public
class UserQueries {
publicstaticvoid main(String[] args) throws Exception {
MBeanServer server = MBeanServerFactory.createMBeanServer();
ObjectName user1 = new ObjectName("book.liuyang:Name=user1");
ObjectName user2 = new ObjectName("book.liuyang:Name=user2");
server.createMBean("com.liuyang.jmx.mbeans.user.User", user1);
server.createMBean("com.liuyang.jmx.mbeans.user.User", user2);
server.setAttribute(user1, new Attribute("Name", "user1"));
server.setAttribute(user2, new Attribute("Name", "user2"));
server.setAttribute(user1, new Attribute("Name", "user1"));
server.setAttribute(user2, new Attribute("Name", "user2"));
server.setAttribute(user1, new Attribute("Role", "code"));
server.setAttribute(user2, new Attribute("Role", "test"));
QueryExp exp = Query.match(Query.attr("Name"),Query.value("user1"));
ObjectName scope = new ObjectName("book.liuyang:*");
Set set = server.queryNames(scope, exp);
Iterator it = set.iterator();
System.out.println("
下列
MBean
的名字是:
user1");
while
(it.hasNext()) {
System.out.println(it.next());
}
scope = new ObjectName("book.liuyang:*");
exp = Query.initialSubString(Query.attr("Role"),Query.value("t"));
set = server.queryNames(scope, exp);
it = set.iterator();
System.out.println("
下列
MBean
的角色是:
test");
while
(it.hasNext()) {
System.out.println(it.next());
}
}
}
在 UserQueries 中创建了两个 MBean 对象:
server.createMBean("com.liuyang.jmx.mbeans.user.User", user1);
这是 MBeanServer 通过 MBean 类的名称创建 MBean 实例的方法。
然后分别设置它们的属性:
server.setAttribute(user1, new Attribute("Name", "user1"));
一个 Attribute 对象代表一个属性。
JMX API 为查询服务建立标准的接口方法,第一步是建立查询表达式:
QueryExp exp = Query.match(Query.attr("Name"),Query.value("user1"));
这个查询表达式是以全匹配的方式进行的, JMX 还支持部分模糊查询的功能:
exp = Query.initialSubString(Query.attr("Role"),Query.value("t"));
initialSubString 建立的查询方法只会匹配名称的开始部分,在这里只要以“ t ”开头的值都会被匹配。
然后,通过一个 MBean 名称对象来代表查询范围:
ObjectName scope = new ObjectName("book.liuyang:*");
最后,通过 MBeanServer 执行查询表达式的操作,得到结果:
Set set = server.queryNames(scope, exp);
运行
UserQueries 可以得到查询结果。