18.2 创建自己的MBean

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中是什么样子。

image-20211023132546372

图18.4 在JConsole中看到的TacoCounter的操作和属性

TacoCounter还有一个技巧,不过这与JMX并没有什么关系。这个类扩展了AbstractRepositoryEventListener,每当通过TacoRepository保存Taco的时候,它都会得到通知。在本例中,在创建和保存新Taco对象的时候,onAfterCreate()方法将会被调用,我们在这里让计数器增加1。AbstractRepositoryEventListener还提供了多个方法来处理对象创建、保存和删除前后的事件。

使用MBean的操作和属性在很大程度上是一个拉取操作。换句话说,就算MBean属性的值发生了变化,除非通过JMX客户端查看该属性,否则我们也不会知道。接下来,我们换一个话题,看一下如何将MBean的通知推送至JMX客户端。