Announcement Announcement Module
Collapse
No announcement yet.
How to expose interceptors to JMX? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to expose interceptors to JMX?

    Given the following definition:

    Code:
        <bean name="performanceMonitoringInterceptor" class="com.mycompany.PerformanceMonitoringInterceptor" />
        
        <bean name="myServiceProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
            <property name="beanNames" value="*Service"/>
            <property name="interceptorNames">
                <list>
                    <value>performanceMonitoringInterceptor</value>       
                </list>
            </property>
        </bean>
    How would I expose the PerformanceMonitoringInterceptor to JMX?

  • #2
    Let me be more clear...

    The assumption is that there are more than one service and hence more than one interceptor that is keeping track of performance stats.

    -Josh

    Comment


    • #3
      If performanceMonitoringInterceptor is defined as singleton, why would you say you'll have "more than one interceptor" ?

      Comment


      • #4
        Andrei,

        Thanks for the response. Perhaps you say may other thread (http://forum.springframework.org/showthread.php?t=43893) where I asked exactly that same question.

        So, if I were to add isSingleton=false, how would I be able to expose those other instances to JMX?

        Regards,

        Josh

        Comment


        • #5
          I don't think there is an out-of-the-box way of doing this...
          One possible solution could be to define a BeanPostProcessor to add all interceptor instances created when proxying in another bean from context. Then, when the MBeanExporter (your custom exporter) is created pass to it the bean that holds all interceptor instances.
          There may be more elegant ways...

          Comment


          • #6
            Still missing pieces...

            If I had "myServiceProxyCreator" implement the BeanPostProcessor interface, that would allow me to obtain a list of beans effected by the "beanNames" mapping rule. For each of these beans, I should be able to obtain their corresponding interceptors.

            Once I get the interceptor though, is there a programatic way I can expose it to JMX?

            -Joshua

            Comment


            • #7
              Something like:
              Code:
              <bean id="myInterceptor" class="my.package.SimpleInterceptor" scope="prototype"/>
              	
              	<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" >
              		<property name="beanNames"><value>*Impl</value></property>
              		<property name="interceptorNames">
              			<list>
              				<value>myInterceptor</value>
              			</list>
              		</property>
              	</bean>
              	
              	<bean class="my.package.CustomPostProcessor" />
              	
              	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" />
              Code:
              public class CustomPostProcessor implements BeanPostProcessor, BeanFactoryAware {
              
                  private BeanFactory beanFactory;
                  
                  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
              	this.beanFactory = beanFactory;
                  }
                  
                  public Object postProcessAfterInitialization(Object bean, String arg1)
              	    throws BeansException {
              	if (bean instanceof SimpleInterceptor) {
              	    MBeanExporter exporter = (MBeanExporter) beanFactory.getBean("exporter");
              	    
              	    try {
              		String name = "my.package.performance" + ":" + "service=myInterceptor,beanName=" + bean.toString();
              		exporter.registerManagedResource(bean, new ObjectName(name));
              	    } catch (MBeanExportException e) {
              		e.printStackTrace();
              	    } catch (MalformedObjectNameException e) {
              		e.printStackTrace();
              	    } catch (NullPointerException e) {
              		e.printStackTrace();
              	    }
              	}
              	
              	return bean;
                  }
              
                  public Object postProcessBeforeInitialization(Object bean, String arg1)
              	    throws BeansException {
              	return bean;
                  }
              }

              Comment


              • #8
                I will give your suggestions a try...

                Andrei,

                I will give your suggestion a try. Thanks for your help.

                Regards,

                Josh

                Comment


                • #9
                  Bummer...

                  This solution does work. The problem is, the interceptor has no context to the bean that it is being applied to. "beanName" is always the name of the interceptor itself.

                  I need the beanName to be the beanName that the interceptor is being applied to. The only bean that has this context is the BeanNameAutoProxyCreator. Overiding the getAdvicesAndAdvisorsForBean method on this bean and registering the MBean there would be an option. An ungly one though.

                  Your thoughts?

                  -Josh

                  Comment

                  Working...
                  X