上面文章講到JmxMBeanServer的構造,這篇文章咱們稍微分析一下JmxMBeanServer是怎麼樣註冊MBean的,其實看完上篇文章,就猜到了。app
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方法了。攔截器的默認實現類:dom
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方法spa
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註冊的時候也仍是註冊的動態DynamicMBeancode
DynamicMBean方法比較長,核心的代碼爲:server
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分支,不然新建一個域。blog
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)方法:get
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方法存了起來。it