Jmx之MBean注册

上面文章讲到JmxMBeanServer的构造,这篇文章我们稍微分析一下JmxMBeanServer是怎么样注册MBean的,其实看完上篇文章,就猜到了。

ObjectName helloName = new ObjectName("jmxBean:name=hello");
server.registerMBean(new Hello(), helloName);

通常我们用上述代码进行注册的。去JmxMBeanServer看了一下registerMBean方法的实现,
    public ObjectInstance registerMBean(Object object, ObjectName name)
        throws InstanceAlreadyExistsException, MBeanRegistrationException,
               NotCompliantMBeanException  {

        return mbsInterceptor.registerMBean(object, cloneObjectName(name));
    }

果然是委托拦截器去调用registerMBean方法了。拦截器的默认实现类:

DefaultMBeanServerInterceptor
    public ObjectInstance registerMBean(Object object, ObjectName name)
        throws InstanceAlreadyExistsException, MBeanRegistrationException,
        NotCompliantMBeanException  {

        // ------------------------------
        // ------------------------------
        Class<?> theClass = object.getClass();

        Introspector.checkCompliance(theClass);

        final String infoClassName = getNewMBeanClassName(object);

        checkMBeanPermission(infoClassName, null, name, "registerMBean");
        checkMBeanTrustPermission(theClass);

        return registerObject(infoClassName, object, name);
    }

调用自己的registerObject方法

    private ObjectInstance registerObject(String classname,
                                          Object object, ObjectName name)
        throws InstanceAlreadyExistsException,
               MBeanRegistrationException,
               NotCompliantMBeanException {

        if (object == null) {
            final RuntimeException wrapped =
                new IllegalArgumentException("Cannot add null object");
            throw new RuntimeOperationsException(wrapped,
                        "Exception occurred trying to register the MBean");
        }

        DynamicMBean mbean = Introspector.makeDynamicMBean(object);

        return registerDynamicMBean(classname, mbean, name);
    }

调用自己的registerDynamicMBean方法,由此我们看到,按照我们注册的标准的StandardMBean注册的时候也还是注册的动态DynamicMBean

DynamicMBean方法比较长,核心的代码为:

final Object resource = getResource(mbean);
context = registerWithRepository(resource, mbean, logicalName);
return new ObjectInstance(logicalName, classname);

我们进入registerWithRepository看到,registerWithRepository方法,调用了repository.addMBean(object, logicalName, context);
    private ResourceContext registerWithRepository(
            final Object resource,
            final DynamicMBean object,
            final ObjectName logicalName)
            throws InstanceAlreadyExistsException,
            MBeanRegistrationException {

        // Creates a registration context, if needed.
        //
        final ResourceContext context =
                makeResourceContextFor(resource, logicalName);


        repository.addMBean(object, logicalName, context);
        // May throw InstanceAlreadyExistsException

        // ---------------------
        // Send create event
        // ---------------------
        if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
            MBEANSERVER_LOGGER.logp(Level.FINER,
                    DefaultMBeanServerInterceptor.class.getName(),
                    "addObject", "Send create notification of object " +
                    logicalName.getCanonicalName());
        }

        sendNotification(
                MBeanServerNotification.REGISTRATION_NOTIFICATION,
                logicalName);

        return context;
    }

进入repository.addMBean方法看到,同一个域的时候走else分支,否则新建一个域。

           final Map<String,NamedObject> moiTb = domainTb.get(dom);
            if (moiTb == null) {
                addNewDomMoi(object, dom, name, context);
                return;
            } else {
                // Add instance if not already present
                String cstr = name.getCanonicalKeyPropertyListString();
                NamedObject elmt= moiTb.get(cstr);
                if (elmt != null) {
                    throw new InstanceAlreadyExistsException(name.toString());
                } else {
                    nbElements++;
                    addMoiToTb(object,name,cstr,moiTb,context);
                }
            }

最后看addMoiToTb(object,name,cstr,moiTb,context)方法:

    private void addMoiToTb(final DynamicMBean object,
            final ObjectName name,
            final String key,
            final Map<String,NamedObject> moiTb,
            final RegistrationContext context) {
        registering(context);
        moiTb.put(key,new NamedObject(name, object));
    }

果然是那个维护的Map,用put方法存了起来。

posted on 2018-08-20 19:13  剑姬  阅读(1960)  评论(0编辑  收藏  举报

导航