2012-02-06 21 views
8

Tiếp theo cấu hình ví dụ khác nhau từ tài liệu mùa xuân cũng như một số diễn đàn trên Internet, ứng dụng tập tin bối cảnh của tôi trông giống như:đăng ký JMX MBean sử dụng Spring trên một JVM độc

<beans> 
    <bean id="dH" class="abc.def.ghi.DH"> 
     <constructor-arg> 
      <value>0</value> 
     </constructor-arg> 
     <property name="num" value="100"/> 
    </bean> 
    <bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"> 
      <property name="beans"> 
       <map> 
        <entry key="bean:name=dH1" value-ref="dH"/> 
       </map> 
      </property> 
    </bean> 
    <bean class="org.springframework.jmx.support.MBeanServerFactoryBean"/> 
</beans> 

Tôi đang chạy này mà không cần bất kỳ container và trên JVM đơn giản. Tôi có thể kết nối với quá trình của mình qua JConsole nhưng MBean không hiển thị. Tuy nhiên việc đăng ký đậu lập trình cho thấy nó thành công.

MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); 
DH dh = new DH(0); 
mbeanServer.registerMBean(dh, new ObjectName("bean:name=dH1")); 

Tôi đã thử chơi với cấu hình Spring mà không thành công. Tôi nghĩ rằng bean không đăng ký với máy chủ MBean đang chạy mà có thể truy cập từ ManagementFactory.getPlatformMBeanServer(). Bất kỳ ý tưởng nào về vấn đề này?

Trả lời

11

Ngoài việc xác định một đậu MBeanServerFactory (như đã nêu trong Nicholasanswer của họ) sử dụng ...

<bean class="org.springframework.jmx.support.MBeanServerFactoryBean"> 
    <property name="locateExistingServerIfPossible" value="true" /> 
</bean> 

... bạn cần phải nói với MBeanExporter gì để quản lý:

Nếu đậu thực hiện một trong các giao diện quản lý JMX, MBeanExporter có thể chỉ cần đăng ký MBean với máy chủ thông qua quá trình tự động dò tìm của nó.

Nếu một bean không thực hiện một trong các giao diện quản lý JMX, MBeanExporter sẽ tạo thông tin quản lý bằng cách sử dụng MBeanInfoAssembler được cung cấp.

Giả sử lớp abc.def.ghi.DH của bạn không thực hiện bất kỳ giao diện JMX, hãy thử định nghĩa của bạn MBeanExporter như:

<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"> 
    <property name="assembler"> 
     <bean 
      class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler" 
     > 
      <property name="managedMethods"> 
       <list> 
        <value>getNum</value> 
       </list> 
      </property> 
     </bean> 
    </property> 
    <property name="beans"> 
     <map> 
      <entry key="bean:name=dH1" value-ref="dH"/> 
     </map> 
    </property> 
</bean> 

Nhìn vào OpenJDK 7, cập nhật 2, xây dựng 21 DefaultMBeanServerInterceptor.java nguồn, dòng 898 tạo ra một DynamicMBean cho đối tượng thông thường:

DynamicMBean mbean = Introspector.makeDynamicMBean(object); 

Tôi chưa sửa lỗi, nhưng tôi đặt cược mbeanServer.registerMBean(dh, new ObjectName("bean:name=dH1")) cuối cùng gọi DefaultMBeanServerInterceptor.registerObject(), tạo ra một DynamicMBean cho bạn và đăng ký đúng các bộ định vị và getters tiêu chuẩn của JavaBean.


Dưới đây là một số tệp thử nghiệm hoạt động bằng Spring Framework 3.0.5 và Oracle HotSpot Java 1.6.0_24. Sau khi đặt biến môi trường CLASSPATH của bạn, chỉ cần chạy javac *.javajava Main và sử dụng VisualVM (hoặc ứng dụng tương tự) để kết nối với ứng dụng java đang chạy để xem MBeans đã đăng ký.

ac.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans 
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans.xsd" 
    default-lazy-init="true" 
> 
    <bean id="test" class="Test" /> 
    <bean class="org.springframework.jmx.support.MBeanServerFactoryBean"> 
     <property name="locateExistingServerIfPossible" value="true" /> 
    </bean> 
    <bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"> 
     <property name="assembler"> 
      <bean 
       class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler" 
      > 
       <property name="managedMethods"> 
        <list> 
         <value>getVal</value> 
         <value>setVal</value> 
        </list> 
       </property> 
      </bean> 
     </property> 
     <property name="beans"> 
      <map> 
       <entry key="bean:name=Test" value-ref="test"/> 
      </map> 
     </property> 
    </bean> 
</beans> 

Test.java:

public class Test { 
    private String val = ""; 
    public String getVal() { 
     return val; 
    } 
    public void setVal(String v) { 
     val = v; 
    } 
} 

Main.java:

import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 
public class Main { 
    public static void main(final String[] args) { 
     ApplicationContext ac = new ClassPathXmlApplicationContext("ac.xml"); 
     try { 
      Thread.sleep(1000 * 60 * 5); 
     } catch (final Throwable t) {} 
    } 
} 
+0

Cảm ơn bạn đã đào bài này ra @Dan. Khi bối cảnh mùa xuân được tải hoặc thậm chí dh được tạo ra bằng cách sử dụng ngữ cảnh dòng Introspector thậm chí không được thực thi. Tuy nhiên việc đăng ký đậu bằng tay không gọi cùng một dòng. Tôi không nghĩ Spring đang cố gắng đăng ký bean với những cấu hình này. Cái gì đó phải bị thiếu ... –

+0

Điều này làm việc cho tôi bằng cách sử dụng Spring 3.0.5 và một JavaBean đơn giản với một trình getter/setter thuộc tính; Tôi có thể kết nối với ứng dụng thử nghiệm đơn giản của mình với VisualVM và xem MBean thử nghiệm đã được đăng ký sử dụng định nghĩa bean 'MBeanExporter' mà tôi đã cung cấp. Hãy thử phá vỡ kịch bản của bạn xuống một hình thức đơn giản, có được rằng để làm việc, sau đó xây dựng nó trở lại lên đến những gì bạn đang có và xem nơi vấn đề của bạn nằm. –

+0

Sử dụng Spring 3.1.0 Tôi đã thử với XML được cung cấp của bạn có và không có -Dcom.sun.management.jmxremote làm tùy chọn chương trình, vẫn không có may mắn. Tôi đang tải ngữ cảnh theo cách sau: Nhà máy BeanFactory = new XmlBeanFactory (new ClassPathResource ("/ application-context.xml")); và sau đó tải MBean dự định là: factory.getBean (DH.class); Tôi biết điều này nghe có vẻ ngây thơ nhưng có cách nào chúng ta có thể kết hợp XML hoàn chỉnh của chúng ta và cấu trúc chương trình đơn giản không? –

2

Sự cố xảy ra với MBeanServerFactoryBean.

Từ javadoc:

Theo mặc định, MBeanServerFactoryBean sẽ luôn tạo ra một MBeanServer mới được ngay cả khi một đang chạy. Để có nỗ lực MBeanServerFactoryBean định vị một MBeanServer đang chạy trước, đặt giá trị của thuộc tính "locateExistingServerIfPossible" thành "true".

Hãy thử cấu hình này:

<bean class="org.springframework.jmx.support.MBeanServerFactoryBean"> 
    <property name="locateExistingServerIfPossible" value="true" /> 
</bean> 

================================ =================

Cố gắng xác định MBeanServer trong đậu xuất khẩu:

<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"> 
    <property name="beans"> 
     <map> 
       <entry key="bean:name=dH1" value-ref="dH" /> 
      </map> 
     </property> 
     <property name="server" ref="MBeanServer" /> 
</bean> 
<bean id="MBeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"> 
    <property name="locateExistingServerIfPossible" value="true" /> 
</bean> 

=========== ================================= ============================

Ok, chúng ta hãy tiếp cận sức mạnh vũ phu và có được nền tảng MBeanServer trực tiếp:

<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"> 
    <property name="beans"> 
     <map> 
       <entry key="bean:name=dH1" value-ref="dH" /> 
      </map> 
     </property> 
     <property name="server"> 
      <bean id="MBeanServer" class="java.lang.management.ManagementFactory" factory-method="getPlatformMBeanServer"/> 
     </property> 
</bean> 
+0

Tôi đã thử nó @Nicholas. Cố gắng một lần nữa quá mà không có may mắn .. –

+0

không có may mắn với điều đó quá .. –

+0

Cảm ơn những gợi ý khác @Nicholas. Mặc dù cố gắng cả hai đều không đăng ký MBeans. –

Các vấn đề liên quan