行为MBeanServerForwarder [英] Behavior MBeanServerForwarder

查看:63
本文介绍了行为MBeanServerForwarder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在此处问了一个问题,但没有得到答案.但是,我继续搜索,发现了一些可以满足我需要的东西:" MBeanServerForwarder ".我阅读了官方的JavaDoc,但对我来说仍然不清楚.

I have asked a question here but I did not get an answer. Howerver, I continue my search and I found something which could please my need : "MBeanServerForwarder". I read the official JavaDoc but it is still not clear for me.

那么,MBeanServerForwarder是否可以充当MBeanServer的代理?即:我可以用它来拦截MBeans注册表,在ObjectName中进行修改并将其转发到MBeanServer吗?

So, does MBeanServerForwarder work as a proxy for a MBeanServer? ie: Can I use it to intercept MBeans registry, make modification in the ObjectName and forward it to the MBeanServer?

谢谢.

推荐答案

是的,但这不是必须的.您只需要实现 MBeanServer 接口并覆盖 registerMBean 方法(也许还可以是 unregisterMBean 方法).

Yes, but it's not really necessary. You only need to implement the MBeanServer interface and override the registerMBean method (and perhaps the unregisterMBean method).

使用真实的MBeanServer作为委托,您的实现可能如下所示:

Using the real MBeanServer as a delegate, here's what your implementation might look like:

    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

ObjectName:sun.management:type=HotspotInternal,serial=-441253090

经过一点思考,您可以设置新的MBeanServer impl.在 java.lang.management.ManagementFactory platformMBeanServer 字段中,您将永久覆盖JVM代理的MBean注册.

With a bit of reflection, you could set your new MBeanServer impl. in the platformMBeanServer field of the java.lang.management.ManagementFactory and you will have permanently overriden the JVM agent's MBean registration.

==========更新===========

此代码段演示了如何黑客平台MBeanServer来提供备用(或包装的)MBeanServer(使用上面的AltObjectNameMBeanServer的 rr 实例:

This code snippet demonstrates how you might hack the platform MBeanServer to supply an alternate (or wrapped) MBeanServer (using the rr instance of AltObjectNameMBeanServer from above:

Field serverField = ManagementFactory.class.getDeclaredField("platformMBeanServer");
serverField.setAccessible(true);
serverField.set(null, rr);
System.out.println("Equal:" + (rr==ManagementFactory.getPlatformMBeanServer()));

==========更新===========

这是我认为您要寻找的简单示例. 参见此要点.

Here's a simple example of what I think you are looking for. See this gist.

如果使用以下选项运行示例:

If you run the example with these options:

-Djavax.management.builder.initial=org.helios.jmx.HeliosMBeanServerBuilder
-Dhelios.jmx.renamer.filter=java.util.logging:*

它将覆盖系统的默认MBeanServerBuilder,并拦截所有与 java.util.logging:* 相匹配的ObjectName的MBean注册.

It will override the system's default MBeanServerBuilder and intercept all MBean registrations with ObjectNames matching java.util.logging:*.

运行 main 时,它将打印所有平台MBeanServer MBean ObjectName,并且输出将如下所示:

When the main runs, it will print all the platform MBeanServer MBean ObjectNames and the output will look like this:

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.

Alternatively, you can create your own instance of the HeliosMBeanServer builder, define the domain name, the filter and the rename strategy and create your own MBeanServer rather than using the platform MBeanServer.

这篇关于行为MBeanServerForwarder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆