一、自定义MBean
public interface HelloMBean {
String getName();
void setName(String name);
String print();
}
HelloMBean必须以MBean
结尾。
@Slf4j
public class Hello implements HelloMBean {
private String name;
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String print() {
log.info(name);
return name;
}
}
@Slf4j是lombok注解。HelloMBean的名称去除MBean
后必须是Hello
,不能是其他名称。这里的资源是Hello
,MBean的接口是必须是HelloMBean
。
在启动类注册MBean:
@SpringBootApplication
@MapperScan("com.example.mytest.mapper")
public class MyTestApplication {
public static void main(String[] args) {
SpringApplication.run(MyTestApplication.class, args);
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
Hello hello = new Hello();
hello.setName("张三");
try {
// ObjectName规范是包名:type=接口名,name=MBean名
ObjectName objectName = new ObjectName("com.example.mytest.mbean:type=HelloMBean,name=hello");
platformMBeanServer.registerMBean(hello, objectName);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
启动程序后,再启动jconsole:
点击属性后,将属性修改为李四,点击下面的刷新。在点击hello MBean的操作
:
属性已经修改为李四。查看控制台:
2023-06-03 16:37:19.095 INFO 71617 --- [on(7)-127.0.0.1] com.example.mytest.mbean.Hello : 李四
在web访问
如果要在web发布,可以使用HtmlAdaptorServer适配器,先引入依赖:
<dependency>
<groupId>org.glassfish.external</groupId>
<artifactId>opendmk_jdmkrt_jar</artifactId>
<version>1.0-b01-ea</version>
</dependency>
将启动类修改为:
@SpringBootApplication
@MapperScan("com.example.mytest.mapper")
public class MyTestApplication {
public static void main(String[] args) {
SpringApplication.run(MyTestApplication.class, args);
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
Hello hello = new Hello();
hello.setName("张三");
try {
ObjectName objectName = new ObjectName("com.example.mytest.mbean:type=HelloMBean,name=hello");
platformMBeanServer.registerMBean(hello, objectName);
HtmlAdaptorServer html = new HtmlAdaptorServer();
ObjectName adaptorName = new ObjectName("adapator:name=HtmlAdaptor");
html.setPort(9097);
MBeanServer platformMBeanServer1 = ManagementFactory.getPlatformMBeanServer();
platformMBeanServer1.registerMBean(html, adaptorName);
html.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
访问http://localhost:9097/
,看到:
点击type=HelloMBean,name=hello:
可以看到中文乱码了。
开放远程访问
如果要开放端口,可以添加JVM参数:
-Dcom.sun.management.jmxremote.port=19999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
第一个参数表示在19999端口监听JMX连接,第二个和第三个参数表示无需验证,不使用SSL连接,在开发测试阶段比较方便,生产环境必须指定验证方式并启用SSL。
启动后,在jconsole中输入:
二、自定义MXBean
public interface MyHelloExampleMXBean {
String getName();
void setName(String name) ;
String print();
}
public class MyHello implements MyHelloExampleMXBean{
private String name;
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String print() {
return name;
}
}
修改启动类:
@SpringBootApplication
@MapperScan("com.example.mytest.mapper")
public class MyTestApplication {
public static void main(String[] args) {
SpringApplication.run(MyTestApplication.class, args);
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
Hello hello = new Hello();
hello.setName("张三");
MyHello myHello = new MyHello();
myHello.setName("李四");
try {
ObjectName objectName = new ObjectName("com.example.mytest.mbean:type=HelloMBean,name=hello");
platformMBeanServer.registerMBean(hello, objectName);
platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
objectName = new ObjectName("com.example.mytest.mbean:type=MyHelloExampleMXBean,name=myHello");
platformMBeanServer.registerMBean(myHello, objectName);
HtmlAdaptorServer html = new HtmlAdaptorServer();
ObjectName adaptorName = new ObjectName("adapator:name=HtmlAdaptor");
html.setPort(9097);
MBeanServer platformMBeanServer1 = ManagementFactory.getPlatformMBeanServer();
platformMBeanServer1.registerMBean(html, adaptorName);
html.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
可以看到MyHelloExampleMXBean只要以MXBean
结尾就可以随便命名。
三、在Spring中定义MBean
MyController:
@Value("${my.value}")
private String myValue;
private Set<String> set = new HashSet<>();
public void add(String s) {
set.add(s);
}
public Set<String> getSet() {
return set;
}
MyControllerMXBean
@Slf4j
@Component
@ManagedResource(objectName = "controller:name=myControllerMXBean", description = "MyController Attribute")
public class MyControllerMXBean {
@Autowired
private MyController myController;
@ManagedAttribute(description = "Get Configuration")
public String getMyValue() {
String myValue = myController.myValue();
log.info(myValue);
return myValue;
}
@ManagedAttribute(description = "Get Set")
public String getSet() {
Set<String> set = myController.getSet();
return set.stream().collect(Collectors.joining());
}
@ManagedOperation
@ManagedOperationParameter(name = "s", description = "Add Set Element")
public void addSet(String s) {
myController.add(s);
}
}
@ManagedResource配置ObjectName,@ManagedOperation指示这是个操作。@ManagedAttribute用在方法上,指示这是个属性(必须符合JAVA Bean的规范,即有get,set方法), @ManagedOperationParameter绑定参数。
用jconsole连接后:
调用addSet后再调用getSet查看添加的数据。getMyValue方法是为了演示可以调用到Spring Bean中的方法获取配置。