18.2 创建自己的MBean
借助Spring,可以很容易地将任意bean导出为JMX MBean。我们唯一需要做的就是在bean类上添加@ManagedResource注解,然后在方法或属性上添加@ManagedOperation或@ManagedAttribute。Spring会负责剩余的事情。
例如,我们想要提供一个MBean,用来跟踪通过Taco Cloud创建了多少个taco订单,那么我们可以定义一个服务bean,在这个服务中保持已创建taco的数量。程序清单18.1展现了该服务。
程序清单18.1 统计已创建taco订单数量的MBean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package tacos.tacos; import java.util.concurrent.atomic.AtomicLong; import org.springframework.data.rest.core.event.AbstractRepositoryEventListener; import org.springframework.jmx.export.annotation.ManagedAttribute; import org.springframework.jmx.export.annotation.ManagedOperation; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.stereotype.Service; @Service @ManagedResource public class TacoCounter extends AbstractRepositoryEventListener<Taco> { private AtomicLong counter; public TacoCounter(TacoRepository tacoRepo) { long initialCount = tacoRepo.count(); this.counter = new AtomicLong(initialCount); } @Override protected void onAfterCreate(Taco entity) { counter.incrementAndGet(); } @ManagedAttribute public long getTacoCount() { return counter.get(); } @ManagedOperation public long increment(long delta) { return counter.addAndGet(delta); } }
|
TacoCounter类使用了@Service注解,所以它将会被组件扫描功能所发现并且会注册一个实例作为bean存放到Spring应用上下文中。它还使用了@ManagedResource注解,表明这个bean是一个MBean。作为MBean,它暴露了一个属性和一个操作。getTacoCount()方法使用了@ManagedAttribute注解,将会暴露为一个MBean属性;而increment()方法使用了@ManagedOperation注解,将会暴露为MBean操作。
图18.4展现了TacoCounter MBean在JConsole中是什么样子。
图18.4 在JConsole中看到的TacoCounter的操作和属性
TacoCounter还有一个技巧,不过这与JMX并没有什么关系。这个类扩展了AbstractRepositoryEventListener,每当通过TacoRepository保存Taco的时候,它都会得到通知。在本例中,在创建和保存新Taco对象的时候,onAfterCreate()方法将会被调用,我们在这里让计数器增加1。AbstractRepositoryEventListener还提供了多个方法来处理对象创建、保存和删除前后的事件。
使用MBean的操作和属性在很大程度上是一个拉取操作。换句话说,就算MBean属性的值发生了变化,除非通过JMX客户端查看该属性,否则我们也不会知道。接下来,我们换一个话题,看一下如何将MBean的通知推送至JMX客户端。