0

事前に作成されたオブジェクトのコレクションを受け取り、それらの MBean を作成するカスタム Spring MBeanExporter を作成しました。関連するクラスの既存のプロパティと操作を取得するだけで、属性と操作を決定するために「デフォルト」戦略を使用しているようです。

「afterPropertiesSet()」メソッドがあり、何らかの作業を行い、基本の「Bean」リストにデータを入力してから、そのスーパークラス メソッドを呼び出します。これはかなりうまく機能します。

関連するクラスで「@Managed...」アノテーションを利用できるかどうかを確認したいと思います。私の最初の試みでは、「Beans」リストの作成方法と処理方法を変更せずに、関連するクラスに予想される注釈を付けただけです。残念ながら、これはうまくいきませんでした。クラス、属性、および操作にいくつかの「説明」属性を追加しましたが、これらは VisualVM に表示されませんでした。

関連するクラスで MBeanExporter メカニズムに @Managed... アノテーションを使用させるためにできることはありますか?

私の現在のクラスは MBeanExporter を拡張していることに注意してください。AnnotationMBeanExporter を拡張するように変更すると、@Managed... アノテーションを持たないクラスで失敗します。クラスで @Managed... アノテーションが見つからない限り、「MBeanExporter」が行うことをデフォルトにするものが必要です。

コードを表示する必要があると思いますが、これはほとんど単なる疑似コードになります。

私の MBeanExporter は次のようになります。

public class MyMBeanExporter extends MBeanExporter {

@Override
public void afterPropertiesSet() {
    // Do some pre-work to determine the list of beans to use.
    Map<String, Object> beans   = new HashMap<String, Object>();
    ... stuff
    setBeans(beans);

    // Now let the superclass create mbeans for all of the beans we found.
    super.afterPropertiesSet();
}

リストに入れられる Bean の 1 つには、次のようなクラスがあります。

@ManagedResource(objectName = ":name=fancystuff", description = "This is some stuff")
public class Stuff {
    private int howMuchStuff;

    @ManagedAttribute(description = "This tells us how much stuff we have")
    public int getHowMuchStuff() { return howMuchStuff; }

    public void setHowMuchStuff(int howMuchStuff) { this.howMuchStuff = howMuchStuff; }

    @ManagedOperation(description = "Use this to add more stuff")
    public void makeSomeMoreStuff(int stuffToAdd) {
        howMuchStuff    += stuffToAdd;
    }
}

これが VisualVM でレンダリングされるとき、@Managed... アノテーションに記述されているメタデータは使用されません。結果として得られる ObjectName は、「@ManagedResource」アノテーションで指定したオーバーライド値ではないため、これは確実にわかります。

代わりに基本クラスを「AnnotationMBeanExporter」に変更すると、このクラスに関連付けられた Bean は、注釈で指定したメタデータを取得します。ただし、「@ManagedResource」アノテーションを持たないクラスに関連付けられている他のすべての Bean はすべて、次のような例外で失敗します。

InvalidMetadataException: No ManagedResource attribute found for class: class ...

私の一時的な回避策は、単純な MBeanExporter サブクラスを定義して、コンストラクター フラグに応じてプレーンな MBeanExporter または AnnotationMBeanExporter として動作できるようにすることです。次に、2 つのインスタンスを簡単に定義できます。1 つはフラグ付き、もう 1 つはフラグなしで、処理するパスのセットが異なります。これは機能します。

次に試みることは、MBeanExporter と AnnotationMBeanExporter を内部で管理する単一の「偽の」MBeanExporter を用意することです。最初の Bean リストを作成しますが、Bean に関連付けられたクラスを調べて @ManagedResource アノテーションが存在するかどうかを確認しながら、それぞれを処理します。これは、AnnotationMBeanExporter または通常の Bean によって処理される Bean のリストに最終的に含まれるかどうかを示します。

更新: 生の AnnotationMBeanExporter を作成して「afterPropertiesSet()」を呼び出すことができないため、この戦略で問題が発生しました。次のエラーで失敗します。

MBeanExportException: Cannot autodetect MBeans if not running in a BeanFactory
4

2 に答える 2