The concept of interceptors exploits the proxy design pattern to enable you to modify the behavior of the MBean server. By default, the MBean server appears from the outside like a hollow shell that simply forwards every operation to the default interceptor. You can replace this default interceptor by another object implementing the same interface, to change the semantics of the MBean server. In most cases, you would use this other object to forward most or all operations to the default interceptor after doing some processing. However, you can also use it to forward some operations to other handlers instead, for instance depending on the object names involved. Figure 7–1 shows schematically how you can insert an interceptor between the MBean server and the default interceptor.
Some examples of the uses of interceptors are as follows:
Imposing security checks – The interceptor performs checks, for example it checks permissions, and only forwards operations that pass the security checks to the default interceptor.
Logging – The interceptor forwards all operations to the default interceptor, but also logs their parameters and results.
Creating virtual MBeans – The interceptor handles operations on MBeans it owns itself, and forwards others to the default interceptor. An interceptor might own all MBeans whose names match a particular pattern, for instance. In this way, MBeans do not necessarily have to be Java objects. This is very useful when there are a great many managed objects, or when they are very volatile.
Interceptors can be composed. When an interceptor is added, it is usually inserted between the MBean server shell and the current interceptor. Initially, the current interceptor is the default one. But if another interceptor has already been inserted, this other interceptor is the current one. Hence, a request could pass through several interceptors on its way to the default interceptor, for example a security checker and a logger.