org.springframework.jmx.access
Class MBeanClientInterceptor

java.lang.Object
  extended by org.springframework.jmx.access.MBeanClientInterceptor
All Implemented Interfaces:
Aware, BeanClassLoaderAware, DisposableBean, InitializingBean
Direct Known Subclasses:
MBeanProxyFactoryBean

public class MBeanClientInterceptor
extends java.lang.Object
implements BeanClassLoaderAware, InitializingBean, DisposableBean

org.aopalliance.intercept.MethodInterceptor that routes calls to an MBean running on the supplied MBeanServerConnection. Works for both local and remote MBeanServerConnections.

By default, the MBeanClientInterceptor will connect to the MBeanServer and cache MBean metadata at startup. This can be undesirable when running against a remote MBeanServer that may not be running when the application starts. Through setting the connectOnStartup property to "false", you can defer this process until the first invocation against the proxy.

This functionality is usually used through MBeanProxyFactoryBean. See the javadoc of that class for more information.

Since:
1.2
Author:
Rob Harrop, Juergen Hoeller
See Also:
MBeanProxyFactoryBean, setConnectOnStartup(boolean)

Nested Class Summary
private static class MBeanClientInterceptor.MethodCacheKey
          Simple wrapper class around a method name and its signature.
 
Field Summary
private  java.lang.String agentId
           
private  java.util.Map<java.lang.String,javax.management.MBeanAttributeInfo> allowedAttributes
           
private  java.util.Map<MBeanClientInterceptor.MethodCacheKey,javax.management.MBeanOperationInfo> allowedOperations
           
private  java.lang.ClassLoader beanClassLoader
           
private  boolean connectOnStartup
           
private  ConnectorDelegate connector
           
private  java.util.Map<java.lang.String,?> environment
           
private  javax.management.MBeanServerInvocationHandler invocationHandler
           
protected  Log logger
          Logger available to subclasses
private  java.lang.Class managementInterface
           
private  javax.management.ObjectName objectName
           
private  java.lang.Object preparationMonitor
           
private  boolean refreshOnConnectFailure
           
private  javax.management.MBeanServerConnection server
           
private  javax.management.MBeanServerConnection serverToUse
           
private  javax.management.remote.JMXServiceURL serviceUrl
           
private  java.util.Map<java.lang.reflect.Method,java.lang.String[]> signatureCache
           
private  boolean useStrictCasing
           
 
Constructor Summary
MBeanClientInterceptor()
           
 
Method Summary
 void afterPropertiesSet()
          Prepares the MBeanServerConnection if the "connectOnStartup" is turned on (which it is by default).
private  java.lang.Object convertDataArrayToTargetArray(java.lang.Object[] array, java.lang.Class targetClass)
           
private  java.util.Collection convertDataArrayToTargetCollection(java.lang.Object[] array, java.lang.Class collectionType, java.lang.Class elementType)
           
protected  java.lang.Object convertResultValueIfNecessary(java.lang.Object result, MethodParameter parameter)
          Convert the given result object (from attribute access or operation invocation) to the specified target class for returning from the proxy method.
 void destroy()
          Invoked by a BeanFactory on destruction of a singleton.
protected  java.lang.Object doInvoke(MethodInvocation invocation)
          Route the invocation to the configured managed resource.
 java.util.Map<java.lang.String,?> getEnvironment()
          Allow Map access to the environment to be set for the connector, with the option to add or override specific entries.
protected  java.lang.Class getManagementInterface()
          Return the management interface of the target MBean, or null if none specified.
protected  java.lang.Object handleConnectFailure(MethodInvocation invocation, java.lang.Exception ex)
          Refresh the connection and retry the MBean invocation if possible.
 java.lang.Object invoke(MethodInvocation invocation)
          Route the invocation to the configured managed resource..
private  java.lang.Object invokeAttribute(java.beans.PropertyDescriptor pd, MethodInvocation invocation)
           
private  java.lang.Object invokeOperation(java.lang.reflect.Method method, java.lang.Object[] args)
          Routes a method invocation (not a property get/set) to the corresponding operation on the managed resource.
protected  boolean isPrepared()
          Return whether this client interceptor has already been prepared, i.e.
 void prepare()
          Ensures that an MBeanServerConnection is configured and attempts to detect a local connection if one is not supplied.
private  void retrieveMBeanInfo()
          Loads the management interface info for the configured MBean into the caches.
 void setAgentId(java.lang.String agentId)
          Set the agent id of the MBeanServer to locate.
 void setBeanClassLoader(java.lang.ClassLoader beanClassLoader)
          Callback that supplies the bean class loader to a bean instance.
 void setConnectOnStartup(boolean connectOnStartup)
          Set whether or not the proxy should connect to the MBeanServer at creation time ("true") or the first time it is invoked ("false").
 void setEnvironment(java.util.Map<java.lang.String,?> environment)
          Specify the environment for the JMX connector.
 void setManagementInterface(java.lang.Class managementInterface)
          Set the management interface of the target MBean, exposing bean property setters and getters for MBean attributes and conventional Java methods for MBean operations.
 void setObjectName(java.lang.Object objectName)
          Set the ObjectName of the MBean which calls are routed to, as ObjectName instance or as String.
 void setRefreshOnConnectFailure(boolean refreshOnConnectFailure)
          Set whether to refresh the MBeanServer connection on connect failure.
 void setServer(javax.management.MBeanServerConnection server)
          Set the MBeanServerConnection used to connect to the MBean which all invocations are routed to.
 void setServiceUrl(java.lang.String url)
          Set the service URL of the remote MBeanServer.
 void setUseStrictCasing(boolean useStrictCasing)
          Set whether to use strict casing for attributes.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

logger

protected final Log logger
Logger available to subclasses


server

private javax.management.MBeanServerConnection server

serviceUrl

private javax.management.remote.JMXServiceURL serviceUrl

environment

private java.util.Map<java.lang.String,?> environment

agentId

private java.lang.String agentId

connectOnStartup

private boolean connectOnStartup

refreshOnConnectFailure

private boolean refreshOnConnectFailure

objectName

private javax.management.ObjectName objectName

useStrictCasing

private boolean useStrictCasing

managementInterface

private java.lang.Class managementInterface

beanClassLoader

private java.lang.ClassLoader beanClassLoader

connector

private final ConnectorDelegate connector

serverToUse

private javax.management.MBeanServerConnection serverToUse

invocationHandler

private javax.management.MBeanServerInvocationHandler invocationHandler

allowedAttributes

private java.util.Map<java.lang.String,javax.management.MBeanAttributeInfo> allowedAttributes

allowedOperations

private java.util.Map<MBeanClientInterceptor.MethodCacheKey,javax.management.MBeanOperationInfo> allowedOperations

signatureCache

private final java.util.Map<java.lang.reflect.Method,java.lang.String[]> signatureCache

preparationMonitor

private final java.lang.Object preparationMonitor
Constructor Detail

MBeanClientInterceptor

public MBeanClientInterceptor()
Method Detail

setServer

public void setServer(javax.management.MBeanServerConnection server)
Set the MBeanServerConnection used to connect to the MBean which all invocations are routed to.


setServiceUrl

public void setServiceUrl(java.lang.String url)
                   throws java.net.MalformedURLException
Set the service URL of the remote MBeanServer.

Throws:
java.net.MalformedURLException

setEnvironment

public void setEnvironment(java.util.Map<java.lang.String,?> environment)
Specify the environment for the JMX connector.

See Also:
JMXConnectorFactory.connect(javax.management.remote.JMXServiceURL, java.util.Map)

getEnvironment

public java.util.Map<java.lang.String,?> getEnvironment()
Allow Map access to the environment to be set for the connector, with the option to add or override specific entries.

Useful for specifying entries directly, for example via "environment[myKey]". This is particularly useful for adding or overriding entries in child bean definitions.


setAgentId

public void setAgentId(java.lang.String agentId)
Set the agent id of the MBeanServer to locate.

Default is none. If specified, this will result in an attempt being made to locate the attendant MBeanServer, unless the "serviceUrl" property has been set.

See Also:

Specifying the empty String indicates the platform MBeanServer.


setConnectOnStartup

public void setConnectOnStartup(boolean connectOnStartup)
Set whether or not the proxy should connect to the MBeanServer at creation time ("true") or the first time it is invoked ("false"). Default is "true".


setRefreshOnConnectFailure

public void setRefreshOnConnectFailure(boolean refreshOnConnectFailure)
Set whether to refresh the MBeanServer connection on connect failure. Default is "false".

Can be turned on to allow for hot restart of the JMX server, automatically reconnecting and retrying in case of an IOException.


setObjectName

public void setObjectName(java.lang.Object objectName)
                   throws javax.management.MalformedObjectNameException
Set the ObjectName of the MBean which calls are routed to, as ObjectName instance or as String.

Throws:
javax.management.MalformedObjectNameException

setUseStrictCasing

public void setUseStrictCasing(boolean useStrictCasing)
Set whether to use strict casing for attributes. Enabled by default.

When using strict casing, a JavaBean property with a getter such as getFoo() translates to an attribute called Foo. With strict casing disabled, getFoo() would translate to just foo.


setManagementInterface

public void setManagementInterface(java.lang.Class managementInterface)
Set the management interface of the target MBean, exposing bean property setters and getters for MBean attributes and conventional Java methods for MBean operations.


getManagementInterface

protected final java.lang.Class getManagementInterface()
Return the management interface of the target MBean, or null if none specified.


setBeanClassLoader

public void setBeanClassLoader(java.lang.ClassLoader beanClassLoader)
Description copied from interface: BeanClassLoaderAware
Callback that supplies the bean class loader to a bean instance.

Invoked after the population of normal bean properties but before an initialization callback such as InitializingBean's InitializingBean.afterPropertiesSet() method or a custom init-method.

Specified by:
setBeanClassLoader in interface BeanClassLoaderAware
Parameters:
beanClassLoader - the owning class loader; may be null in which case a default ClassLoader must be used, for example the ClassLoader obtained via ClassUtils.getDefaultClassLoader()

afterPropertiesSet

public void afterPropertiesSet()
Prepares the MBeanServerConnection if the "connectOnStartup" is turned on (which it is by default).

Specified by:
afterPropertiesSet in interface InitializingBean

prepare

public void prepare()
Ensures that an MBeanServerConnection is configured and attempts to detect a local connection if one is not supplied.


retrieveMBeanInfo

private void retrieveMBeanInfo()
                        throws MBeanInfoRetrievalException
Loads the management interface info for the configured MBean into the caches. This information is used by the proxy when determining whether an invocation matches a valid operation or attribute on the management interface of the managed resource.

Throws:
MBeanInfoRetrievalException

isPrepared

protected boolean isPrepared()
Return whether this client interceptor has already been prepared, i.e. has already looked up the server and cached all metadata.


invoke

public java.lang.Object invoke(MethodInvocation invocation)
                        throws java.lang.Throwable
Route the invocation to the configured managed resource..

Parameters:
invocation - the MethodInvocation to re-route
Returns:
the value returned as a result of the re-routed invocation
Throws:
java.lang.Throwable - an invocation error propagated to the user
See Also:
doInvoke(MethodInvocation), handleConnectFailure(MethodInvocation, java.lang.Exception)

handleConnectFailure

protected java.lang.Object handleConnectFailure(MethodInvocation invocation,
                                                java.lang.Exception ex)
                                         throws java.lang.Throwable
Refresh the connection and retry the MBean invocation if possible.

If not configured to refresh on connect failure, this method simply rethrows the original exception.

Parameters:
invocation - the invocation that failed
ex - the exception raised on remote invocation
Returns:
the result value of the new invocation, if succeeded
Throws:
java.lang.Throwable - an exception raised by the new invocation, if it failed as well
See Also:
setRefreshOnConnectFailure(boolean), doInvoke(MethodInvocation)

doInvoke

protected java.lang.Object doInvoke(MethodInvocation invocation)
                             throws java.lang.Throwable
Route the invocation to the configured managed resource. Correctly routes JavaBean property access to MBeanServerConnection.get/setAttribute and method invocation to MBeanServerConnection.invoke.

Parameters:
invocation - the MethodInvocation to re-route
Returns:
the value returned as a result of the re-routed invocation
Throws:
java.lang.Throwable - an invocation error propagated to the user

invokeAttribute

private java.lang.Object invokeAttribute(java.beans.PropertyDescriptor pd,
                                         MethodInvocation invocation)
                                  throws javax.management.JMException,
                                         java.io.IOException
Throws:
javax.management.JMException
java.io.IOException

invokeOperation

private java.lang.Object invokeOperation(java.lang.reflect.Method method,
                                         java.lang.Object[] args)
                                  throws javax.management.JMException,
                                         java.io.IOException
Routes a method invocation (not a property get/set) to the corresponding operation on the managed resource.

Parameters:
method - the method corresponding to operation on the managed resource.
args - the invocation arguments
Returns:
the value returned by the method invocation.
Throws:
javax.management.JMException
java.io.IOException

convertResultValueIfNecessary

protected java.lang.Object convertResultValueIfNecessary(java.lang.Object result,
                                                         MethodParameter parameter)
Convert the given result object (from attribute access or operation invocation) to the specified target class for returning from the proxy method.

Parameters:
result - the result object as returned by the MBeanServer
targetClass - the result type of the proxy method that's been invoked
Returns:
the converted result object, or the passed-in object if no conversion is necessary

convertDataArrayToTargetArray

private java.lang.Object convertDataArrayToTargetArray(java.lang.Object[] array,
                                                       java.lang.Class targetClass)
                                                throws java.lang.NoSuchMethodException
Throws:
java.lang.NoSuchMethodException

convertDataArrayToTargetCollection

private java.util.Collection convertDataArrayToTargetCollection(java.lang.Object[] array,
                                                                java.lang.Class collectionType,
                                                                java.lang.Class elementType)
                                                         throws java.lang.NoSuchMethodException
Throws:
java.lang.NoSuchMethodException

destroy

public void destroy()
Description copied from interface: DisposableBean
Invoked by a BeanFactory on destruction of a singleton.

Specified by:
destroy in interface DisposableBean