创建自己的MBean
借助Spring,可以很容易地将任意bean导出为JMX MBean。我们唯一需要做的就是在bean类上添加@ManagedResource注解,然后在方法或属性上添加@ManagedOperation或@ManagedAttribute。Spring会处理剩余的事情。
例如,我们想要提供一个MBean,用来跟踪通过Taco Cloud创建了多少个taco订单,那么可以定义一个服务bean,在这个服务中保存已创建taco的数量。程序清单17.1展现了该服务。
package tacos.jmx;
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;
import tacos.Taco;
import tacos.data.TacoRepository;
@Service
@ManagedResource
public class TacoCounter
extends AbstractRepositoryEventListener<Taco> {
private AtomicLong counter;
public TacoCounter(TacoRepository tacoRepo) {
tacoRepo
.count()
.subscribe(initialCount -> {
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操作。图17.4展现了TacoCounter MBean在JConsole中的样子。

关于TacoCounter,还有一个技巧,不过与JMX并没有什么关系——它扩展了Abstract RepositoryEventListener,每当通过TacoRepository保存Taco的时候,它都会得到通知。在本例中,创建和保存新Taco对象时,onAfterCreate()方法会被调用,我们在这里让计数器增加1。AbstractRepositoryEventListener还提供了多个方法来处理对象创建、保存和删除前后的事件。
使用MBean的操作和属性在很大程度上是一个拉取操作。换句话说,如果MBean属性的值发生了变化,除非通过JMX客户端查看该属性,否则我们也不会知道。接下来,我们换一个话题,看一下如何将MBean的通知推送至JMX客户端。