As we know, Standard MBean is easy to use and implement, but it requires that the MBean interface has to be stable. If the manageable resoures are evolving over time, we need Dynamic MBean to help us out of this situation, but what if modifying the existing class is not an option? Then Model MBean come to your rescue. Actually the Model MBean is Dynamic MBean since it extends from Dynamic MBean interface, some peopel might get confused about this, why can't we just use Dynamic MBean to handle this since the Model MBean is also Dynamic MBean? That's a good question. Recall from the development of Dynamic MBean, we have to modify our manageable resource to implement Dynamic MBean interface, right? And the creation of MBeanInfo is inside the Dynamic MBean. But the Model MBean is different, you can create your MBeanInfo outside of the Model MBean and you don't have to develop your MBean since JMX has offered a default implementation for you, RequiredModelMBean.
Now, let's take a look at the architecture of the Model MBean provided by Sun first.
Well, as we can see from the above image, Model MBean extends from DynamicMBean,PersistentMBean and ModelMBeanNotificationBroadcaster. PersistentMBean provides the persistence mechanism for ModelMBean, you can save your ModelMBean to the local file or a remote database depends on the implementation of your PersistentMBean. And ModelMBeanNotificationBroadcaster is actually a NotificationBroadcaster, you can send out attribute change-related notifications or the general notifications via it since this interface has offered the sendNotification(Notification ntfyObj) method and sendAttributeChangeNotification(AttributeChangeNotification notification) method respectively.
In the meantime, Model MBean provide some additional features, such as Attribute value caching, Notification logging and Operation delegating. In fact, these features are implementing by using the Descriptor interface. Before we talk about the Descriptor interface, we need to examin the metadata in the Model MBean first. As stated earlier, Model MBean is Dynamic MBean, thus its management interface is created at runtime like Dynamic MBean. Model MBean has its own metadata like MBeanFeatureInfo in Dynamic MBean, and the following image will give you a clear understanding of metadatas in Model MBean and their relationships with those ones in Dynamic MBean.
Besides that, we can also see that every metadata class of Model MBean contains a Descriptor instance. As we said earlier, Model MBean use Descriptor to implements its additional features like Attribute value caching we mentioned earlier. A Descriptor contains a number of fieldName-fieldValue pairs, each fieldName is represented by a String Object while each fieldValue is represented by a Object instance. Each Descriptor instance in different metadata class of Model MBean contains different predefined attributes, take Descriptor instance in ModelAttributeMBeanInfo for example, the predefined attributes are as below:
I am sure you can understand most of them without explanations. And the attribute value caching feature in the ModelMBean is implemented by using the predefined attributes:currencyTimeLimit and lastUpdatedTimeStamp. As the description of currencyTimeLimit shows, when its value is less than 0, the attribute will be never cached, and if its value is equal to 0, then the attribute will be always cached, otherwise its value indicates the time period that the cached value is valid, in this case, if the sum of currencyTimeLimit and lastUpdatedTimeStamp is greater than the present time, then the cached attribute value will be refreshed. And you might be wondering where the cached attribute value will be stored. In fact, the cached attribute value will be stored in the predefined attribute 'value' of corresponding Descriptor instance, which you can find in the above table.
When you comprehend the theory of Attribute value caching, it is easy to understand other additional features provided by Model MBean, like operation delegating. Operation delegation allows you invoke some operations that is not defined in your managed resource. This feature is also implemented by its Descriptor's predefined attribute:targetObject and targetType
If you set an object that is different from your managed resource in the targetObject attribute of Descriptor instance, when invoking an operation, it will try to invoke this operation on the Model MBean first , then the targetObject and your managed resource finally.
After we examine the metedata of the Model MBean, let's get back to our Model MBean interface again.
public interface ModelMBean extends DynamicMBean, PersistentMBean, ModelMBeanNotificationBroadcaster { public void setModelMBeanInfo(ModelMBeanInfo inModelMBeanInfo) throws MBeanException, RuntimeOperationsException; public void setManagedResource(Object mr, String mr_type) throws MBeanException, RuntimeOperationsException, InstanceNotFoundException, InvalidTargetObjectTypeException ; }
ModelMBean interface exposes two operations, one for setting its managed resource and the other for setting its ModelMBeanInfo metadata.And as we mentioned earlier, ModelMBean is also a DynamicMBean, and recall how we develop the DynamicMBean, you will find that the ModelMBeanInfo passing to the setModelMBeanInfo() method is actually the one returned by DynamicMBean#getMBeanInfo() method at most time. In fact, when you are implementing a ModelMBean, you're actually implementing a Dynamic MBean. Instead of using RequiredModelMBean, you can also implement your own ModelMBean, at most of time, there is no need for us to use so many features. Maybe you don't want all the additional features come with the Descriptor and maybe you think MBeanInfo is enough(after all, you need to do more when using a ModelMBeanInfo, for example, ModelMBeaninfo requires a additional param Descriptor when creating while MBeanInfo not). Then you can implement your own Model MBean like the following,
public interface ModelMBean extends DynamicMBean { public void setMBeanInfo(MBeanInfo mbeanInfo) ; public void setManagedResource(Object mr); }
That's to say, you can define your ModelMBean interface at your will according to your requirements.
Same as DynamicMBean, it's a great challenge to construct its ModelMBeanInfo, the common way is write a helper to ease the development of constructing ModelMBeanInfo, like the following codes show:
public void addModelMBeanAttribute( String fname,String ftype, boolean read, boolean write, boolean is, String description, Descriptor desc ) { attributes.put( fname, new ModelMBeanAttributeInfo(fname, ftype, description,read,write,is, desc ) ); } public void addModelMBeanConstructor( Constructor c, String description, Descriptor desc ) { this.constructors.put( c, new ModelMBeanConstructorInfo( description, c, desc ) ); }
And a better way is to configure them in a propery file such as xml file, and then map them into corresponding Model MBean metadata like spring does.