Да, но это совсем не обязательно. Вам нужно только реализовать интерфейс MBeanServer и переопределить метод registerMBean (и, возможно, метод unregisterMBean).
Используя настоящий MBeanServer в качестве делегата, вот как может выглядеть ваша реализация:
public class AltObjectNameMBeanServer implements MBeanServer {
protected final MBeanServer innerServer;
protected final ObjectName filter;
public AltObjectNameMBeanServer(MBeanServer innerServer, ObjectName filter) {
this.innerServer = innerServer;
this.filter = filter;
}
public ObjectInstance registerMBean(Object object, ObjectName name) throws InstanceAlreadyExistsException,
MBeanRegistrationException, NotCompliantMBeanException {
if(filter.apply(name)) {
name = reformat(name);
}
return innerServer.registerMBean(object, name);
}
public static ObjectName reformat(ObjectName on)
try {
int id = on.toString().hashCode();
return new ObjectName(new StringBuilder(on.toString()).append(",serial=").append(id).toString());
} catch (Exception e) {
throw new RuntimeException("Failed to reformat [" + on + "]", e);
}
}
// ======== Put direct delegates for all other methods =======
}
Пример использования:
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
AltObjectNameMBeanServer rr = new AltObjectNameMBeanServer(server, new ObjectName("*:*"));
Class clazz = Class.forName("sun.management.HotspotInternal");
HotspotInternalMBean obj = (HotspotInternal)clazz.newInstance();
ObjectInstance oi = rr.registerMBean(new StandardMBean(obj, HotspotInternalMBean.class), new javax.management.ObjectName("sun.management:type=HotspotInternal"));
System.out.println("ObjectName:" + oi.getObjectName());
Результат:
ObjectName:sun.management:type=HotspotInternal,serial=-441253090
Немного поразмыслив, вы можете установить свой новый MBeanServer impl. в поле platformMBeanServer в java.lang.management.ManagementFactory, и вы навсегда переопределите регистрацию MBean агента JVM.
========== Обновление =============
Этот фрагмент кода демонстрирует, как вы можете взломать платформу MBeanServer, чтобы предоставить альтернативный (или обернутый) MBeanServer (используя экземпляр rr AltObjectNameMBeanServer из приведенного выше:
Field serverField = ManagementFactory.class.getDeclaredField("platformMBeanServer");
serverField.setAccessible(true);
serverField.set(null, rr);
System.out.println("Equal:" + (rr==ManagementFactory.getPlatformMBeanServer()));
========== Обновление =============
Вот простой пример того, что, я думаю, вы ищете. См. эту суть.
Если вы запустите пример с этими параметрами:
-Djavax.management.builder.initial=org.helios.jmx.HeliosMBeanServerBuilder
-Dhelios.jmx.renamer.filter=java.util.logging:*
Он переопределит системный MBeanServerBuilder по умолчанию и перехватит все регистрации MBean с именами объектов, соответствующими java.util.logging:*.
Когда main запустится, он напечатает все имена объектов MBean MBeanServer платформы, и вывод будет выглядеть следующим образом:
MBeanServer Interceptor Test
java.lang:type=MemoryPool,name=PS Eden Space
java.lang:type=Memory
java.lang:type=MemoryPool,name=PS Survivor Space
java.lang:type=GarbageCollector,name=PS MarkSweep
java.lang:type=MemoryPool,name=Code Cache
java.lang:type=Runtime
java.lang:type=ClassLoading
java.lang:type=Threading
java.lang:type=Compilation
com.sun.management:type=HotSpotDiagnostic
java.lang:type=MemoryPool,name=PS Perm Gen
java.util.logging:type=Logging,serial=-132046985
java.lang:type=OperatingSystem
java.lang:type=GarbageCollector,name=PS Scavenge
java.lang:type=MemoryPool,name=PS Old Gen
java.lang:type=MemoryManager,name=CodeCacheManager
JMImplementation:type=MBeanServerDelegate
Обратите внимание на переименование java.util.logging:type=Logging,serial=-132046985.
В качестве альтернативы вы можете создать свой собственный экземпляр построителя HeliosMBeanServer, определить доменное имя, фильтр и стратегию переименования и создать свой собственный MBeanServer, а не использовать платформу MBeanServer.
person
Nicholas
schedule
09.04.2012