# 20.1.3　使用注解驱动的 MBean

除了我向你展示的 MBean 信息装配器，Spring 还提供了另一种装配器 —— MetadataMBeanInfoAssembler，这种装配器可以使用注解标识哪些 bean 的方法需要暴露为 MBean 的托管操作和属性。我完全可以向你展示如何使用这种装配器，但我不会这么做。这是因为手工装配它非常繁杂，仅仅是为了使用注解并不值得这么做。相反，我将向你展示如何使用 Spring context 配置命名空间中的 \<context:mbean-export> 元素。这个便捷的元素装配了 MBean 导出器以及为了在 Spring 启用注解驱动的 MBean 所需要的装配器。我们所需要做的就是使用它来替换我们之前所使用的 MBeanExporter bean:

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

现在，要把任意一个 Spring bean 转变为 MBean，我们所需要做的仅仅是使用 @ManagedResource 注解标注 bean 并使用 @ManagedOperation 或 @ManagedAttribute 注解标注 bean 的方法。例如，如下的程序清单展示了如何使用注解把 SpittleController 导出为 MBean。

{% code title="程序清单 20.1 通过注解把 HomeController 转变为 MBean" %}

```java
package com.habuma.spittr.mvc;

import java.util.Map;
import org.springframework.beans,factory.annotation.Autowired;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.habuma.spittr.service.SpittrService;

@Controller
@ManagedResource(objectName="spitter:name=SpittleController")
public class SpittleController {

  @ManagedAttribute
  public void setSpittlesPerPage(int spittlesPerPage) {
    this.spittlesPerPage = spittlesPerPage;
  }
  
  @ManagedAttribute
  public int getSpittlesPerPage() {
    return spittlesPerPage;
  }
}
```

{% endcode %}

在类级别使用了 @ManagedResource 注解来标识这个 bean 应该被导出为 MBean。objectName 属性标识了域（Spitter）和 MBean 的名称（SpittleController）。

spittlesPerPage 属性的存取器方法都使用了 @ManagedAttribute 注解来进行标注，这表示该属性应该暴露为 MBean 的托管属性。注意，其实并不需要使用注解同时标注这两个存取器方法。如果我们选择仅标注 setSpittlesPerPage() 方法，那我们仍可以通过 JMX 设置该属性，但这样的话我们将不能查看该属性的值。相反，如果仅仅标注 getSpittlesPerPage() 方法，那我们可以通过 JMX 查看该属性的值，但无法修改该属性的值。

同样需要提醒一下，我们还可以使用 @ManagedOperation 注解替换 @ManagedAttribute 注解来标注存取器方法。如下所示：

```java
@ManagedOperation
public void setSpittlesPerPage(int spittlesPerPage) {
  this.spittlesPerPage = spittlesPerPage;
}

@ManagedOperation
public int getSpittlesPerPage() {
  return spittlesPerPage;
}
```

这会将方法暴露为 MBean 的托管操作，但是并不会把 spittlesPerPage 属性暴露为 MBean 的托管属性。这是因为在暴露 MBean 功能时，使用 @ManagedOperation 注解标注方法是严格限制方法的，并不会把它作为 JavaBean 的存取器方法。因此，使用 @ManagedOperation 可以用来把 bean 的方法暴露为 MBean 托管操作，而使用 @ManagedAttribute 可以把 bean 的属性暴露为 MBean 托管属性。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://potoyang.gitbook.io/spring-in-action-v4/untitled-13/untitled-3/untitled-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
