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方法存了起來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM