There is nothing that statically indicates that our MBean sends attribute change notifications. In our case it is a design decision, meaning that we know that the listener will receive attribute change notifications because we wrote the MBean that way. At runtime, the MBean server exposes the list of notifications in this MBean's metadata object, allowing a manager that is interested in attribute changes to register the appropriate listener.
Being confined to the agent, our example is much simpler. First we instantiate and register our simple MBean with the agent's MBean server. Then, because we have designed them to work together, we can add our listener for attribute changes to our MBean. Since we have kept a direct reference to the MBean instance, we can call its addNotificationListener method directly, without going through the MBean server.
SimpleStandard simpleStd = null; ObjectName simpleStdObjectName = null; SimpleStandardListener simpleStdListener = null; [...] try { simpleStdObjectName = new ObjectName("simple_mbean:class=SimpleStandard"); simpleStd = new SimpleStandard(); myAgent.myMBeanServer.registerMBean(simpleStd, simpleStdObjectName); } catch(Exception e) { e.printStackTrace(); System.exit(0); } echo("\nAdding the simple standard MBean listener..."); try { simpleStdListener = new SimpleStandardListener(); simpleStd.addNotificationListener(simpleStdListener, null, null); } catch(Exception e) { e.printStackTrace(); System.exit(0); } echo("done"); |
There are several major implications to adding our listener directly to the MBean instance:
Notification objects, or in this case subclasses, will contain a direct reference to the broadcaster object. This means that their getSource method will return a reference to the broadcaster instead of its object name. Our listener is unaffected by this issue since it never calls this method.
This listener will need to be removed directly from the MBean instance. A listener added directly to the broadcaster object cannot be removed through the MBean server's methods, and vice versa.
The rest of the Agent object's code performs the setup of the agent's MBean server and various input and output for running the example. Similar agents were already presented in detail in the lesson on "Agent Applications".