第20章-使用JMX管理Spring Bean

本文详细介绍了如何使用Spring的JMX模块将Spring Bean导出为MBean,包括通过名称暴露方法、使用接口定义MBean操作、注解驱动的MBean以及处理MBean冲突。此外,还探讨了远程管理Spring Bean和处理JMX通知的方法,为运行时管理应用配置提供了可能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用JMX管理Spring Bean

学习内容

Spring bean暴露为MBean

远程管理Spring Bean

处理JMX通知

应用背景

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

JMX这项技术能够让我们管理、监视和配置应用。

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

标准MBean:标准MBean的管理接口是通过在固定的接口上执行反射确定的,bean类会实现这个接口;

动态MBean:动态MBean的管理接口是在运行时通过调用DynamicMBean接口的方法来确定的。因为管理接口不是通过静态接口定义的,因此可以在运行时改变;

开放MBean:开放MBean是一种特殊的动态MBean,其属性和方法只限定于原始类型、原始类型的包装类以及可以分解为原始类型或原始类型包装类的任意类型;

模型MBean:模型MBean也是一种特殊的动态MBean,用于充当管理接口与受管资源的中介。模型Bean并不像它们所声明的那样来编写。它们通常通过工厂生成,工厂会使用元信息来组装管理接口

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

Spring bean导出为MBean

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

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

@Bean

public MBeanExporter mBeanExporter(SpittleController spittleController) {

MBeanExporter exporter = new MBeanExporter();

Map<String, Object> beans = new HashMap<String, Object>();

beans.put("spitter:name=Controller", spittleController);

exporter.setBeans(beans);

return exporter;

}

配置MBeanExporter的最简单方式是为他的beans属性配置一个Map集合,该集合中的元素是我们希望暴露为JMX MBean的一个或多个bean。每个Map条目的key就是Mbean的名称(由管理域的名字和一个key-value对组成,在SpittleController MBean示例中是spittername=Controller),而Map条目的值则是需要暴露的Spring bean引用。

为了对MBean的属性和操作获得更细粒度的控制,Spring提供了几种选择,包括:

通过名称来声明需要暴露或忽略的bean方法;

通过为bean增加接口来选择要暴露的方法;

通过注解标注bean来标识托管的属性和操作。

MBean的服务器从何处而来

如果没有提供MBean服务器,我们就需要在Spring上下文中配置一个MBean服务器

XML配置中,<Contextmbean-server>元素可以为我们实行该功能。

如果使用Java配置的话,我们需要更直接的方式,也就是配置类型位MBeanServerFactoryBeanbean

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

1、通过名称暴露方法

Mbean信息装配器时限制那些方法和属性将在Mbean上暴露的关键。

MethodNameBasedMBeanInfoAssembler,这个装配器指定了需要暴露为Mbean操作的方法名称列表。Java代码配置如下:

@Bean

public MBeanExporter mBeanExporter(SpittleController spittleController) {

MBeanExporter exporter = new MBeanExporter();

Map<String, Object> beans = new HashMap<String, Object>();

beans.put("spitter:name=Controller", spittleController);

exporter.setBeans(beans);

exporter.setAssembler(assembler());

return exporter;

}

 

@Bean

public MethodNameBasedMBeanInfoAssembler assembler() {

MethodNameBasedMBeanInfoAssembler assembler =

new MethodNameBasedMBeanInfoAssembler();

assembler.setManagedMethods(new String[] {

"getSpitlesPerPage", "setSpitlesPerPage"

});

return assembler;

}

MethodExclusionMBeanInfoAssembler是用于指定不需要暴露为Mbean托管操作的方法名称列表。

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

InterfaceBasedMBeanInfoAssembler是另一种MBean信息装配器,可以让我们通过使用接口来选择bean的那些方法需要暴露为MBean的托管操作。

@Bean

public MBeanExporter mBeanExporter(SpittleController spittleController) {

MBeanExporter exporter = new MBeanExporter();

Map<String, Object> beans = new HashMap<String, Object>();

beans.put("spitter:name=Controller", spittleController);

exporter.setBeans(beans);

exporter.setAssembler(interfaceAssembler());

return exporter;

}

@Bean

public InterfaceBasedMBeanInfoAssembler interfaceAssembler() {

InterfaceBasedMBeanInfoAssembler assembler =

new InterfaceBasedMBeanInfoAssembler();

assembler.setManagedInterfaces(

new Class[] {ControllerOperation.class});

return assembler;

}

 

public interface ControllerOperation {

public int getSpitlesPerPage();

public void setSpitlesPerPage(int spitlesPerPage);

  public List<Spittle> spittles(

      long max,

      int count);

}

3、使用注解驱动的MBean

注解配置如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

<!-- Root Context: defines shared resources visible to all other web components -->

<context:mbean-export server="mbeanServer"/>

</beans>

 

@Controller

@RequestMapping("/spittles")

@ManagedResource(objectName="spitter:name=Controller")

public class SpittleController {

    private static final int DEFAULT_PER_PAGE = 25;

    private int spitlesPerPage = DEFAULT_PER_PAGE;

  @ManagedAttribute

public int getSpitlesPerPage() {

return spitlesPerPage;

}

  @ManagedAttribute

public void setSpitlesPerPage(int spitlesPerPage) {

this.spitlesPerPage = spitlesPerPage;

}

}

4、处理MBean冲突

@Bean

public MBeanExporter mBeanExporter(SpittleController spittleController) {

MBeanExporter exporter = new MBeanExporter();

Map<String, Object> beans = new HashMap<String, Object>();

beans.put("spitter:name=Controller", spittleController);

exporter.setBeans(beans);

exporter.setAssembler(interfaceAssembler());

exporter.setRegistrationPolicy(RegistrationPolicy.IGNORE_EXISTING);

return exporter;

}

 

 

远程MBean

 

。。。。。。。。。。。。。。。。

处理通知

JMX通知是MBean与外部世界主动通信的一种方法,而不是等待外部应用对MBean进行查询以获得信息。

1、发送通知

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

 

@Controller

@RequestMapping("/spittles")

@ManagedResource(objectName="spitter:name=Controller")

@ManagedNotification(notificationTypes="SpittleNotifier.OneMillion", name="TODO")

public class SpittleController implements NotificationPublisherAware, SpittleNotifier{

  private NotificationPublisher notificationPublisher;

   @Override

   public void setNotificationPublisher(NotificationPublisher notificationPublisher) {

  // TODO Auto-generated method stub

  this.notificationPublisher = notificationPublisher;

  }

@Override

public void millionPosted() {

// TODO Auto-generated method stub

notificationPublisher.sendNotification(

new Notification("SpittleNotifier.OneMillion", this, 0));

}

}

2、监听通知

接收Mbean通知的标注方法是实现javax.management.NotificationListener接口。

还需要将监听器注册到MbeanExportersetNotificationListenerMappings

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值