一、JMX

Spring对DI的支持是通过在应用中配置bean属性,这是一种非常不错的方法。不过,一旦应用已经部署并且正在运行,单独使用DI并不能帮助我们改变应用的配置。假设我们希望深入了解正在运行的应用并要在运行时改变应用的配置,此时,就可以使用Java管理扩展(JavaManage- ment Extensions,JMX)了。

JMX这项技术能够让我们管理、监视和配置应用。这项技术最初作为Java的独立扩展,从Java 5开始,JMX已经成为标准的组件。

使用JMX管理应用的核心组件是托管bean(managed bean,MBean)。所谓的MBean就是暴露特定方法的JavaBean,这些方法定义了管理接口。JMX规范定义了如下4种类型的MBean:

  • 标准MBean:标准MBean的管理接口是通过在固定的接口上执行反射确定的,bean类会实现这个接口;
  • 动态MBean:动态MBean的管理接口是在运行时通过调用DynamicMBean接口的方法来确定的。因为管理接口不是通过静态接口定义的,因此可以在运行时改变;
  • 开放MBean:开放MBean是一种特殊的动态MBean,其属性和方法只限定于原始类型、原始类型的包装类以及可以分解为原始类型或原始类型包装类的任意类型;
  • 模型MBean:模型MBean也是一种特殊的动态MBean,用于充当管理接口与受管资源的中介。模型Bean并不像它们所声明的那样来编写。它们通常通过工厂生成,工厂会使用元信息来组装管理接口。

Spring的JMX模块可以让我们将Spring bean导出为模型MBean,这样我们就可以查看应用程序的内部情况并且能够更改配置——甚至在应用的运行期。

二、将Spring bean导出为MBean

Spring的MBeanExporter是将Spring Bean转变为MBean的关键。MBeanExporter可以把一个或多个Spring bean导出为MBean服务器(MBean server)内的模型 MBean。MBean服务器(有时候也被称为MBean代理)是MBean生存的容器。对MBean的访问,也是通过MBean服务器来实现的。

如图所示,将Spring bean导出为JMX MBean之后,可以使用基于JMX的管理工具(例如JConsole或者VisualVM)查看正在运行的应用程序,显示bean的属性并调用bean的方法。

下面的@Bean方法在Spring中声明了一个MBeanExporter,它会将spittleControllerbean导出为一个模型MBean:

配置MBeanExporter的最简单方式是为它的beans属性配置一个Map集合,该集合中的元素是我们希望暴露为JMX MBean的一个或多个bean。每个Map条目的key就是MBean的名称(由管理域的名字和一个key-value对组成,在SpittleController MBean示例中是spitter:name=HomeController),而Map条目的值则是需要暴露的Spring bean引用。在这里,我们将输出spittleControllerbean,以便它的属性可以通过JMX在运行时进行管理。

通过MBeanExporter,spittleControllerbean将作为模型MBean以SpittleController的名称导出到MBean服务器中,以实现管理功能。下图展示了通过JConsole查看SpittleControllerMBean时的情况。

SpittleController所有的public成员都被导出为MBean的操作或属性。这可能并不是我们所希望看到的结果,我们真正需要的只是可以配置spittlesPerPage属性。我们不需要调用spittles()方法或SpittleController中的其他方法或属性。因此,我们需要一个方式来筛选所需要的属性或方法。

MBean服务器从何处而来

根据以上配置,MBeanExporter会假设它正在一个应用服务器中(例如Tomcat)或提供MBean服务器的其他上下文中运行。但是,如果Spring应用程序是独立的应用或运行的容器没有提供MBean服务器,我们就需要在Spring上下文中配置一个MBean服务器。

在XML配置中,<context:mbean-server>元素可以为我们实现该功能。如果使用Java配置的话,我们需要更直接的方式,也就是配置类型为MBeanServerFactoryBean的bean(这也是在XML中<context:mbean-server>元素所作的事情)。

MBeanServerFactoryBean会创建一个MBean服务器,并将其作为Spring应用上下文中的bean。默认情况下,这个bean的ID是mbeanServer。了解到这一点,我们就可以将它装配到MBeanExporter的server属性中用来指定MBean要暴露到哪个MBean服务器中。

2.1 通过名称暴露方法

MBean信息装配器(MBean info assembler)是限制哪些方法和属性将在MBean上暴露的关键。其中有一个MBean信息装配器是MethodNameBasedMBean-InfoAssembler。这个装配器指定了需要暴露为MBean操作的方法名称列表。

managedMethods属性可以接受一个方法名称的列表,指定了哪些方法将暴露为MBean的操作。

另一个基于方法名称的装配器是MethodExclusionMBeanInfoAssembler。这个MBean信息装
配器是MethodNameBaseMBeanInfoAssembler的反操作。它不是指定哪些方法需要暴露为MBean的托管操作,MethodExclusionMBeanInfoAssembler指定了不需要暴露为MBean托管操作的方法名称列表

2.1 使用接口定义MBean的操作和属性

Spring的InterfaceBasedMBeanInfoAssembler是另一种MBean信息装配器,可以让我们通过使用接口来选择bean的哪些方法需要暴露为MBean的托管操作。InterfaceBasedMBeanInfoAssembler与基于方法名称的装配器很相似,只不过不再通过罗列方法名称来确定暴露哪些方法,而是通过列出接口来声明哪些方法需要暴露。

例如,假设我们定义了一个名为SpittleControllerManagedOperations的接口,如下所
示:

在这里,我们选择了setSpittlesPerPage()方法和getSpittlesPerPage()方法作为需要暴露的方法。再次提醒,这一对存取器方法间接暴露了spittlesPerPage属性作为MBean的托管属性。为了应用此装配器,我们只需要使用如下的assemblerbean替换之前基于方法名称的装配器即可:

2.3 使用注解驱动的MBean

Spring context配置命名空间中的<context:mbean-export>元素。这个便捷的元素装配了MBean导出器以及为了在Spring启用注解驱动的MBean所需要的装配器。我们所需要做的就是使用它来替换我们之前所使用的MBeanExporterbean:

现在,要把任意一个Spring bean转变为MBean,我们所需要做的仅仅是使用@ManagedResource注解标注bean并使用@ManagedOperation或@ManagedAttribute注解标注bean的方法。例如,如下的程序清单展示了如何使用注解把SpittleController导出为MBean。

在类级别使用了@ManagedResource注解来标识这个bean应该被导出为MBean。objectName属性标识了域(Spitter)和MBean的名称(SpittleController)。

们还可以使用@ManagedOperation注解替换@ManagedAttribute注解来标注存取器方法。如下所示:

2.4 处理MBean冲突

如果MBean服务器中不存在与我们MBean名字相同的已注册的MBean,那我们的MBean注册时就不会有任何问题。但是如果名字冲突时,将会发生什么呢?
默认情况下,MBeanExporter将抛出InstanceAlreadyExistsException异常,该异常表明MBean服务器中已经存在相同名字的MBean。不过,我们可以通过MBeanExporter的registrationBehaviorName属性或者<context:mbean-export>的registration属性指定冲突处理机制来改变默认行为。

Spring提供了3种借助registrationBehaviorName属性来处理MBean名字冲突的机制:

  • FAIL_ON_EXISTING:如果已存在相同名字的MBean,则失败(默认行为);
  • IGNORE_EXISTING:忽略冲突,同时也不注册新的MBean;
  • REPLACING_EXISTING:用新的MBean覆盖已存在的MBean;

例如,如果我们使用MBeanExporter,我们可以通过设置registration-BehaviorName属性为RegistrationPolicy.IGNORE_EXISTING来忽略冲突,如下所示:

registrationBehaviorName属性可以接受RegistrationPolicy中所定义的枚举值,每一个取值分别对应3种冲突处理机制的一种。

三、远程MBean

3.1 暴露远程MBean

3.2 访问远程MBean

要想访问远程MBean服务器,我们需要在Spring上下文中配MbeanServerConnectionFactoryBean。下面的bean声明装配了一个MbeanServerConnectionFactoryBean,

顾名思义,MBeanServerConnectionFactoryBean是一个可用于创建MbeanServer-Connection的工厂bean。由MBeanServerConnectionFactoryBean所生成的MBeanServerConnection实际上是作为远程MBean服务器的本地代理。它能够以MBeanServerConnection的形式注入到其他bean的属性中:

MBeanServerConnection提供了多种方法,我们可以使用这些方法查询远程MBean服务器并调用MBean服务器内所注册的MBean的方法。例如,如果我们希望知道在远程MBean服务器中有多少已注册的MBean,可以用如下的代码片段打印这些信息:

3.3 代理MBean

BcanProxyFactoryBean可以让我们可以直接访问远程的MBean(就如同配置在本地的其他bean一样)。
下图展示了它的工作原理。

例如,考虑如下的MBeanProxyFactoryBean声明:

objectName属性指定了远程MBean的对象名称。在这里是引用我们之前导出的SpittleControllerMBean。
server属性引用了MBeanServerConnection,通过它实现MBean所有通信的路由。在这里,我们注入了之前配置的MBeanServerConnectionFactoryBean。
最后,proxyInterface属性指定了代理需要实现的接口。
对于上面声明的remoteSpittleControllerMBean,我们现在可以把它注入到类型为SpittleControllerManagedOperations的bean属性中,并使用它来访问远程的MBean。这样,我们就可以调用setSpittlesPerPage()和getSpittlesPerPage()方法了。

四、处理通知

通过查询MBean获得信息只是查看应用状态的一种方法。但当应用发生重要事件时,如果希望能够及时告知我们,这通常不是最有效的方法。

例如,假设Spittr应用保存了已发布的Spittle数量,而我们希望知道每发布一百万Spittle时的精确时间(例如一百万、两百万、三百万等)。一种解决方法是编写代码定期查询数据库,计算Spittle的数量。但是执行这种查询会让应用和数据库都很繁忙,因为它需要不断的检查Spittle的数量。

与重复查询数据库获得Spittle的数量相比,更好的方式是当这类事件发生时让MBean通知我们。JMX通知(JMX notification,如下图 所示)是MBean与外部世界主动通信的一种方法,而不是等待外部应用对MBean进行查询以获得信息。

Spring通过NotificationPublisherAware接口提供了发送通知的支持。任何希望发送通知的MBean都必须实现这个接口。

正如我们所看到的,SpittleNotifierImpl实现了NotificationPublisherAware接口。这并不是一个要求苛刻的接口,它仅要求实现一个方法:setNotificationPublisher。
SpittleNotificationImpl也实现了SpittleNotifier接口的方法:millionthSpittlePosted()。这个方法使用了setNotificationPublisher()方法所注入的NotificationPublisher来发送通知:我们的Spittle数量又到了一个新的百万级别。
一旦sendNotification()方法被调用,就会发出通知。

4.1 监听通知

接收MBean通知的标准方法是实现javax.management.NotificationListener接口。例如,考虑一下PagingNotificationListener:

PagingNotificationListener是一个典型的JMX通知监听器。当接收到通知时,将会调用handleNotification()方法处理通知。大概的逻辑可能是,PagingNotification-Listener的handleNotification()方法将向寻呼机或手机上发送消息来告知Spittle数量又到了一个新的百万级别(我把实际的实现留给读者自己完成)。
剩下的工作只需要使用MBeanExporter注册PagingNotificationListener:

MBeanExporter的notificationListenerMappings属性用于在监听器和监听器所希望监听的MBean之间建立映射。在本示例中,我们建立了PagingNotificationListener来监听由SpittleNotifier MBean所发布的通知。

Spring 与JMX相关推荐

  1. spring源码分析之spring jmx

    JMX架构定义: https://docs.oracle.com/javase/8/docs/technotes/guides/jmx/overview/architecture.html Archi ...

  2. JMX和Spring –第2部分

    这篇文章从本教程的第1部分继续. 嗨,在我的前一篇文章中,我解释了如何通过Spring设置JMX服务器以及如何通过身份验证和授权保护对它的访问. 在本文中,我将展示如何实现一个简单的MBean,该MB ...

  3. Spring 2.0.1 与 BEA WebLogic Server 9.2 的集成

    http://www.oracle.com/technetwork/cn/topics/entarch/spring-2-weblogic-server-9-integrat-091510-zhs.h ...

  4. spring默认缓存管理器_使用Spring的缓存管理器缓存Web内容

    spring默认缓存管理器 在这篇文章中,我想向大家展示如何使用Spring的CacheManager,@ Cacheable和JMX批注来缓存和管理Web内容的缓存的基础知识. 想象一下一个网上商店 ...

  5. spring jmx_JMX和Spring –第2部分

    spring jmx 这篇文章从本教程的第1部分继续. 嗨,在我的上一篇文章中,我解释了如何通过Spring设置JMX服务器以及如何通过身份验证和授权保护对它的访问. 在本文中,我将展示如何实现一个简 ...

  6. 使用Spring的缓存管理器缓存Web内容

    在这篇文章中,我想向您展示如何使用Spring的CacheManager,@ Cacheable和JMX批注来缓存和管理Web内容的缓存的基础知识. 想象一下一个网上商店,它从远程WCMS(Web内容 ...

  7. 【jmx】JMX最佳实践与详解

    1.概述 转载:https://www.iteye.com/blog/shift-alt-ctrl-2404103 2.JMX最佳实践 1.Object Names(对象命名) 每个JMX MBean ...

  8. spring实战(第4版读书笔记)

    一  spring的核心 1.主要概念 DI能够让相互协作的软件组件保持松散耦合,而面向切面编程(AOP)允许你把遍布应用各处的功能分离出来形成可重用的组件. spring有两类容器实现方式,bean ...

  9. Spring 4 官方文档学习 Spring与Java EE技术的集成

    本部分覆盖了以下内容: Chapter 28, Remoting and web services using Spring -- 使用Spring进行远程和web服务 Chapter 29, Ent ...

最新文章

  1. c语言输入学生成绩q退出,哭诉、拜求C语言学生成绩管理系统
  2. 从AX4.0本地化SP2凭证系统的一个bug看UserConnection的使用
  3. easy-ui表单校验---针对单个字段,多重校验(有参数校验+无参数检验)
  4. css设置字体颜色、文本对齐方式、首行缩进、文本装饰、列表样式、鼠标样式、禁止文本域拖拽、轮廓线、块级元素对齐方式、文字溢出设置
  5. Tomcat 通用组件
  6. Spring中AOP源码剖析
  7. IOS-网络(数据安全:MD5加密)
  8. 使用protues仿真stm32教程
  9. Overlay网络和VXLAN
  10. 复旦大学2018--2019学年第二学期(18级)高等代数II期末考试第八大题解答
  11. Tableau安装详解及密钥申请
  12. Arduino ESP8266利用定时器中断控制LED闪烁示例程序
  13. 添加滑条进行图像叠加
  14. Rust的审核团队突然宣布集体辞职
  15. DONET牛人应该知道些什么
  16. 让windows xp 自动登录的两种方法及脚本
  17. Android Studio 安装与配置
  18. Android: Kotlin 材料设计入门
  19. 基于易语言写QQ音乐播放器
  20. 计算机冷门领域,毕业后很吃香的三大“冷门”专业!不比热门专业差,适合中等考生...

热门文章

  1. 检查内存泄露的工具--valgrind
  2. Spring IoC容器与Bean管理
  3. 教你如何用CSS修改图片颜色
  4. 艾司博讯:拼多多退款率过高会影响权重吗
  5. Mockito的@Mock与@MockBean
  6. 一篇文章入门HTML5
  7. 【Python基础】之深浅拷贝
  8. 淘宝开放平台4月1日收费 分成比例下调为2/8
  9. 菜鸟自学之——SRA Toolkit 的下载和使用
  10. aspera下载sra文件linux,使用aspera下载.fastq.gz和.sra数据