眾所周知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>