How Can I Add An Interceptor To An XMBean?
JBoss XMBeans introduced in the 3.2.x series provide the ability to plugin
interceptors to the MBean invocation chain. Those interceptors need to
implement the org.jboss.mx.interceptor.Interceptor interface and they
are specified statically in the xmbean descriptor when the MBean gets
deployed.
This is a nice feature of JBoss that predates the JBoss AOP technology and
allows you to code to an interceptor design. It is by no means as powerful
as JBoss AOP, but it is simple and will work, as long as you are dealing
with (X)MBeans.
The interceptor(s) can be instantiated at the MBean level, so they will intercept
all mbean attribute and operation access, for example:
<!-- Sample from ejb-deployer --> ... <xmbean> <description>The EJBDeployer responsible for ejb jar deployment</description> <descriptors> <interceptors> <interceptor code="org.jboss.mx.interceptor.DynamicInterceptor"></interceptor> <!-- HERE --> </interceptors> </descriptors> <class>org.jboss.ejb.EJBDeployer</class> ...
Interceptors can also be specified at attribute/operation level to intercept
access to a particular attribute/operation, for example:
<!-- Sample from jmx-invoker-service.xml --> ... <operation> <description>The detached invoker entry point</description> <name>invoke</name> <parameter> <description>The method invocation context</description> <name>invocation</name> <type>org.jboss.invocation.Invocation</type> </parameter> <return-type>java.lang.Object</return-type> <!-- Uncomment to require authenticated users <descriptors> <interceptors> <!-- HERE --> <interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor" securityDomain="java:/jaas/jmx-console"></interceptor> </interceptors> </descriptors> --> </operation> </xmbean> ...
The code attribute provides the full class name of the XMBean interceptor.
The interceptor can also be initialized with parameters, if it provides
simple type JavaBean-style setters, like the securityDomain attribute
shown in the previous example.
Writing an XMBean Interceptor
You need to implement the org.jboss.mx.interceptor.Interceptor interface.
Most jboss interceptors, however, extend org.jboss.mx.interceptor.AbstractInterceptor.
The interceptor needs to provide either a public default constructor, or
a public constructor taking a single org.jboss.mx.server.MBeanInvoker
argument. (Note: you normally don't need to use this; the invoker is the
target Model MBeans that wraps any deployed MBean in jboss. This acts, more
or less, as a proxy to the actual MBean and it knows how to dispatch calls to it.)
The interceptor can have simple type java-bean style setters in order to
receive one or more configuration values at instantiation time. For example:
public void setSecurityDomain(String securityDomain) throws Exception { ... }
The interceptor is instantiated and configured when the XMBean is instantiated.
There will be one instance of the interceptor for every appearence in the
XMBean descriptor. Normally, we just need one instance of the interceptor
for the whole MBean.
The whole point in the interceptor is to override the invoke() method,
inspect requests that go through and provide some extra capability,
then usually forward the call and return the result. You can also choose to
not forward the request to the target mbean by returning a result immediatelly
(effectively replying on behalf of the target mbean), or throwing an exception.
public Object invoke(Invocation invocation) throws Throwable { // Do your thing here ... // call the next in the interceptor chain, // if nobody follows dispatch the call Interceptor next = invocation.nextInterceptor(); if (next != null) { return next.invoke(invocation); } else { return invocation.dispatch(); } }
XMBean interceptors can be found in the jboss source code. The two real XMBean
interceptors we have used in this example can be found here:
Related:
HowDoIXMBeanIzeAnExistingStandardMBean
Referenced by:
Comments