众所周知Jboss依赖于JMX来装载MBean服务,而这些MBean服务组成了具体服务器实例的差异性。标准JBoss发布版本提供的所有功能都是基于MBean的。所以,如果要为JBoss服务器添加新的服务,最好的方法是开发自己的JMX MBean服务。
MBean服务的生命周期是由如下三个JBoss MBean负责的:SARDeployer、ServiceConfigurator、ServiceController。
如自定义MBean服务依赖于其他MBean服务,可以通过如下方法实现:
1、在自定义MBean接口中添加Service中任何方法。
这种方式避免了对JBoss具体接口的依赖。
2、为自定义MBean接口扩展org.jboss.system.Service接口。
3、为自定义MBean接口扩展org.jboss.system.ServiceMBean接口。
最简单的办法是将自定义MBean接口继承于ServiceMBean接口,将MBean实现类继承ServiceMBeanSupport类。ServiceMBeanSupport已经实现了ServiceMBean接口,ServiceMBeanSupport还集成了日志、JBoss服务状态管理跟踪功能,这些方法需要我们具体实现createService、startService、stopService和destroyService中的部分方法。
下面介绍基于ServiceMBean接口和ServiceMBeanSupport类的JNDIMapMBean接口及其JNDIMap实现类。
package org.joss.chap2.ex2;
import javax.naming.NamingException;
import org.jboss.system.ServiceMBean;
public interface JNDIMapMBean extends ServiceMBean
{
public String getJndiName();
public void setJndiName(String jndiName) throws NamingException;
}
package org.joss.chap2.ex2;
import java.util.HashMap;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NamingException;
import org.jboss.naming.NonSerializableFactory;
import org.jboss.system.ServiceMBeanSupport;
public class JNDIMap extends ServiceMBeanSupport implements JNDIMapMBean
{
private String jndiName;
private HashMap contextMap = new HashMap();
public JNDIMap()
{
super();
// TODO Auto-generated constructor stub
}
public String getJndiName()
{
return jndiName;
}
public void setJndiName(String jndiName) throws NamingException
{
String oldName = this.jndiName;
this.jndiName = jndiName;
if(super.getState()==STARTED)
{
unbind(oldName);
try
{
rebind();
}
catch(Exception e)
{
NamingException ne = new NamingException("Failed to update jndiName");
ne.setRootCause(e);
throw ne;
}
}
}
public void startService()throws Exception
{
rebind();
}
public void stopService()
{
unbind(jndiName);
}
private void rebind() throws NamingException
{
InitialContext rootCtx = new InitialContext();
Name fullName = rootCtx.getNameParser("").parse(jndiName);
NonSerializableFactory.rebind(fullName,contextMap,true);
}
private void unbind(String jndiName)
{
try
{
InitialContext rootCtx = new InitialContext();
rootCtx.unbind(jndiName);
NonSerializableFactory.unbind(jndiName);
}
catch(NamingException e)
{
System.out.println(e);
}
}
public String getName()
{
// TODO Auto-generated method stub
return null;
}
public int getState()
{
// TODO Auto-generated method stub
return 0;
}
public String getStateString()
{
// TODO Auto-generated method stub
return null;
}
public void jbossInternalLifecycle(String arg0) throws Exception
{
// TODO Auto-generated method stub
}
public void create() throws Exception
{
// TODO Auto-generated method stub
}
public void start() throws Exception
{
// TODO Auto-generated method stub
}
public void stop()
{
// TODO Auto-generated method stub
}
public void destroy()
{
// TODO Auto-generated method stub
}
public ObjectName preRegister(MBeanServer arg0, ObjectName arg1)
throws Exception
{
// TODO Auto-generated method stub
return null;
}
public void postRegister(Boolean arg0)
{
// TODO Auto-generated method stub
}
public void preDeregister() throws Exception
{
// TODO Auto-generated method stub
}
public void postDeregister()
{
// TODO Auto-generated method stub
}
}
<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="org.joss.chap2.ex2.JNDIMap"
name="chap2.ex2:service=JNDIMap">
<attribute name="JndiName">inmemory/map/MapTest</attribute>
<depends>jboss:service=Naming</depends>
</mbean>
</server>