Spring내 JMX지원은 당신에게 쉽게 기능을 제공하고 당신의 Spring애플리케이션을 JMX내부구조와 투명하게 통합한다.
특별히 Spring의 JMX지원은 4개의 핵심 기능을 제공한다.
JMX MBean처럼 어느 Spring bean의 자동 등록
당신 bean의 관리 인터페이스를 제어하기 위한 유연한 기법
원격, JSR-160 연결자를 넘어선 MBean의 명시적인 제시(exposure)
local과 remote MBean자원 모두의 간단한 프록시화
이러한 기능들은 Spring이나 JMX인터페이스 와 클래스를 위한 애플리케이션 컴포넌트를 커플링하지 않는 작업을 위해 다지인되었다. 물론 당신 애플리케이션 클래스의 대부분을 위해 Spring JMX기능의 장점을 가져가기 위한 Spring이나 JMX를 인식할 필요는 없다.
Spring의 JMX 프레임워크내 핵심(core) 클래스는 MBeanExporter이다. 이 클래스는 당신의 Spring bean을 가져오고 그것들을 JMX MBeanServer에 등록하는 책임이 있다. 예를 들어, 다음의 클래스를 보라.
package org.springframework.jmx; public class JmxTestBean implements IJmxTestBean { private String name; private int age; private boolean isSuperman; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public int add(int x, int y) { return x + y; } public void dontExposeMe() { throw new RuntimeException(); } }
MBean의 속성과 작업(operation)처럼 이 bean의 프라퍼티와 메소드를 드러내기 위해 당신은 당신의 설정파일내 MBeanExporter 클래스의 인스턴스를 간단하게 설정하고 밑에서 보여지는것처럼 bean으로 전달한다.
<beans> <!-- this bean must not be lazily initialized if the exporting is to happen --> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"> <property name="beans"> <map> <entry key="bean:name=testBean1" value-ref="testBean"/> </map> </property> </bean> <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> </beans>
위 설정조각의 적절한 bean정의는 exporter bean이다. beans 프라퍼티는 JMX MBeanServer에 내보내져야하는 당신의 bean이 어떠한 것인지 MBeanExporter에 알리기 위해 사용된다. 디폴트 설정내에서, beans Map의 각각의 항목 key는 관련 항목값에 의해 참조되는 bean을 위한 ObjectName처럼 사용된다. 이 행위는 Section 20.5, “당신의 bean을 위한 ObjectName 제어하기”부분에서 언급된것처럼 변경될수 있다.
testBean bean를 설정하는것은 ObjectNamebean:name=testBean1 하위의 MBean처럼 드러난다. 디폴트에 의해, bean의 모든 public성격의 프라퍼티는 속성과 모든 public성격의 메소드(Object 클래스로 부터 상속된)가 작업(operation)처럼 드러나는 만큼 드러난다.
위 설정은 애플리케이션이 이미 실행중인 하나의(그리고 오직 하나의) MBeanServer를 가진 환경에서 실행중이라는것을 가정한다. 이 경우 Spring은 실행중인 MBeanServer를 할당하고 그 서버와 함께 당신의 bean을 등록할것이다. 이 행위는 당신의 애플리케이션이 자신만의 MBeanServer를 가진 톰캣이나 IBM웹스피어와 같은 컨테이너내부에서 실행중일때 유용하다.
어쨌든, 이 접근법은 독립형(standalone) 환경이나 MBeanServer를 제공하지 않는 컨테이너내부에서 실행될때는 필요없다. 이것을 할당하기 위해 당신은 당신의 설정을 위한 org.springframework.jmx.support.MBeanServerFactoryBean의 인스턴스를 추가하여 선언적으로 MBeanServer인스턴스를 생성할수 있다. 당신은 또한 MBeanServer가 MBeanExporter의 server 프라퍼티의 값을 MBeanServerFactoryBean에 의해 반환되는 MBeanServer값으로 셋팅하여 사용하는지 확인할수 있다.
<beans>
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
<!--
this bean needs to be eagerly pre-instantiated in order for the exporting to occur;
this means that it must not be marked as lazily initialized
-->
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=testBean1" value-ref="testBean"/>
</map>
</property>
<property name="server" ref="mbeanServer"/>
</bean>
<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
<property name="name" value="TEST"/>
<property name="age" value="100"/>
</bean>
</beans>
여기, MBeanServer의 인스턴스는 MBeanServerFactoryBean에 의해 생성되고 서버 프라퍼티를 통해 MBeanExporter에 제공된다. 당신이 당신 자신의 MBeanServer 인스턴스를 제공할때 MBeanExporter는 수행중인 MBeanServer에 할당하기 위해 시도하지 않을것이고 제공되는 MBeanServer 인스턴스를 사용할것이다. 이 작업을 정확하게 하기 위해 당신은 classpath에 JMX구현물의 위치시켜야만 한다.
명시된 서버가 없다면, MBeanExporter는 구동중인 MBeanServer를 자동으로 감지하도록 시도한다. 이것은 오직 하나의 MBeanServer 인스턴스가 사용된 환경에서 작동한다. 어쨌든 다중 인스턴스가 존재할때, exporter는 나쁜 서버를 잡을것이다. 이러한 경우, 사용된 인스턴스를 표시하기 위해 MBeanServer agentId를 사용할것이다.
<beans>
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<!-- indicate to first look for a server -->
<property name="locateExistingServerIfPossible" value="true"/>
<!-- search the MbeanServer instance with the given agentId -->
<property name="agentId" value="<MBeanServer instance agentId>"/>
</bean>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="server" ref="mbeanServer"/>
...
</bean>
</beans>
존재하는 MBeanServer이 lookup메소드를 통해 가져오는 동적/알려지지 않은 agentId를 가지는 플랫폼/경우를 위해 factory-method를 사용해야만 한다:
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="server"> <!-- Custom MBeanServerLocator --> <bean class="platform.package.MBeanServerLocator" factory-method="locateMBeanServer"/> </property> ... </bean> </beans>
만약 당신이 MBeanExporter을 가진 bean을 설정한다면 그것은 늦은(lazy) 초기화를 위해 설정되고 그 다음 MBeanExporter는 이 규칙을 깨지 않을것이고 bean을 인스턴스화하는것을 피할것이다. 대신 이것은 MBeanServer을 가지고 프록시를 등록할것이고 프록시의 첫번째 호출이 발생할때까지 컨테이너로 부터 bean을 얻는것을 미룰것이다.
MBeanExporter와 이미 유효한 MBeans으로 부터 보내어진 bean은 Spring으로 부터 더이상의 조정(intervention) 없이 MBeanServer처럼 등록된다. MBean은 autodetect 프라퍼티를 true로 셋팅하여 MBeanExporter에 의해 자동적으로 감지될수 있다.
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="autodetect" value="true"/> </bean> <bean name="spring:mbean=true" class="org.springframework.jmx.export.TestDynamicMBean"/>
여기에, spring:mbean=true 라고 불리는 bean은 벌써 유효한 JMX MBean이고 Spring에 의해 자동으로 등록될것이다. 디폴트에 의하면 JMX등록을 위해 자동감지된 bean은 ObjectName으로 사용된 bean이름을 가진다. 이 행위는 Section 20.5, “당신의 bean을 위한 ObjectName 제어하기”부분에서 상세화된것처럼 오버라이드될수 있다.
Spring MBeanExporter가 ObjectName 'bean:name=testBean1'를 사용하여 MBeanServer로 MBean을 등록하는 시나리오를 생각해보자. 만약 MBean 인스턴스가 같은 ObjectName 아래에서 이미 등록되었다면, 디폴트 행위는 실패한다(그리고 InstanceAlreadyExistsException를 던진다.).
MBean이 MBeanServer와 등록될때 발생하는 것의 행위를 제어하는 것은 가능하다. Spring의 JMX지원은 등록절차가 MBean이 같은 ObjectName아래에서 이미 등록된것을 찾았을때 등록행위를 제어하기 위한 3가지의 다른 등록행위를 허용한다. 이 등록행위는 아래의 테이블에서 나열된다.
Table 20.1. 등록 행위
등록 행위 | 설명 |
---|---|
REGISTRATION_FAIL_ON_EXISTING | 이것은 디폴트 등록행위이다. MBean인스턴스가 같은 ObjectName아래에서 이미 등록되었다면, 등록된 MBean은 등록되지 않을것이고 InstanceAlreadyExistsException가 던져질것이다. 존재하고 있는 MBean은 영향을 받지 않는다. |
REGISTRATION_IGNORE_EXISTING | MBean인스턴스가 같은 ObjectName아래에서 이미 등록되었다면, 등록된 MBean은 등록되지 않을것이다. 존재하는 MBean은 영향을 받지 않는다. 그리고 던져지는 Exception은 없다. 이것은 다중 애플리케이션이 공유 MBeanServer내 공통 MBean을 공유하길 원하는 셋팅에 유용하다. |
REGISTRATION_REPLACE_EXISTING | MBean인스턴스가 같은 ObjectName아래 이미 등록되었다면, 이미 등록된 존재하는 MBean은 등록되지 않을것이고 새로운 MBean은 대신 등록될것이다.(새로운 MBean은 이전 인스턴스를 효과적으로 대체한다.) |
위 값들(REGISTRATION_FAIL_ON_EXISTING, REGISTRATION_IGNORE_EXISTING, 그리고 REGISTRATION_REPLACE_EXISTING)은 MBeanRegistrationSupport클래스의 상수처럼 정의된다(MBeanExporter클래스는 이것의 수퍼클래스에서 나온다.). 만약 당신이 디폴트 등록 행위를 변경하길 원한다면, 당신은 MBeanExporter정의의 registrationBehaviorName프라퍼티의 값을 이러한 값중 하나로 셋팅할 필요가 있다.
아래의 예제는 디폴트 등록 행위로부터 REGISTRATION_REPLACE_EXISTING 행위로 변경하는 효과를 주는 방법을 보여준다.
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <map> <entry key="bean:name=testBean1" value-ref="testBean"/> </map> </property> <property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING"/> </bean> <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> </beans>
이전의 예제에서 당신 bean의 관리 인터페이스를 조금(public 프라퍼티 모두와 JMX속성과 개별 작업처럼 드러나는 각각의 bean) 제어한다. 내보내어진 bean의 프라퍼티와 메소드를 잘 제어하는 것은 JMX속성과 작업처럼 실질적으로 드러난다. Spring JMX는 당신 bean의 관리 인터페이스를 제어하기 위한 포괄적이고 확장가능한 기법을 제공한다.
MBeanExporter는 드러난 각각의 bean의 관리 인터페이스를 정의하는 책임을 지닌 org.springframework.jmx.export.assembler.MBeanInfoAssembler 인터페이스의 구현물을 위임한다. 디폴트 구현물인 org.springframework.jmx.export.assembler.SimpleReflectiveMBeanInfoAssembler 는 (당신이 이전 예제에서 본것처럼) 모든 public성격의 프라퍼티와 메소드를 드러내는 인터페이스를 간단하게 정의한다. Spring은 소스레벨 메타데이타(metadata)나 어느 임의의 인터페이스를 사용하여 관리 인터페이스를 제어하도록 허용하는 MBeanInfoAssembler 인터페이스의 두개의 추가적인 구현물을 제공한다.
MetadataMBeanInfoAssembler를 사용하여 당신은 소스레벨 메타데이타를 사용하는 당신의 bean을 위한 관리 인터페이스를 정의할수 있다. 메타데이타 읽기는 org.springframework.jmx.export.metadata.JmxAttributeSource 인터페이스에 의해 캡슐화된다. Spring JMX는 Commons Attributes를 위한 org.springframework.jmx.export.metadata.AttributesJmxAttributeSource 인터페이스와 JDK 5.0 annotations을 위한 org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource 인터페이스의 두가지 구현물을 위한 지원을 제공한다. MetadataMBeanInfoAssembler는 정확하게 기능을 위한 JmxAttributeSource의 구현물이 설정되어야만 한다. 이 예제를 위해 우리는 Commons Attributes 메타데이타 접근법을 사용할것이다.
JMX로 내보내기 위한 bean을 표시하기 위해 당신은 ManagedResource 속성으로 bean의 클래스에 주석(annotate)을 달아야 한다. Commons Attributes 메타데이타 접근법의 경우 이 클래스는 org.springframework.jmx.metadata 패키지에서 찾을수 있다. 당신이 작업(operation)처럼 드러내기를 바라는 각각의 메소드는 ManagedOperation속성으로 표시되어야만 하고 당신이 드러내길 바라는 각각의 프라퍼티는 ManagedAttribute속성으로 표시되어야 한다. 프라퍼티를 표시할때 당신은 쓰기전용(write-only)이나 읽기전용(read-only) 속성을 위한 getter이나 setter를 생략할수 있다.
밑의 예제는 당신이 좀더 먼저 본 JmxTestBean 클래스가 Commons Attributes 메타데이타로 표시된다는것을 보여준다.
package org.springframework.jmx; /** * @@org.springframework.jmx.export.metadata.ManagedResource * (description="My Managed Bean", objectName="spring:bean=test", * log=true, logFile="jmx.log", currencyTimeLimit=15, persistPolicy="OnUpdate", * persistPeriod=200, persistLocation="foo", persistName="bar") */ public class JmxTestBean implements IJmxTestBean { private String name; private int age; /** * @@org.springframework.jmx.export.metadata.ManagedAttribute * (description="The Age Attribute", currencyTimeLimit=15) */ public int getAge() { return age; } public void setAge(int age) { this.age = age; } /** * @@org.springframework.jmx.export.metadata.ManagedAttribute * (description="The Name Attribute", currencyTimeLimit=20, * defaultValue="bar", persistPolicy="OnUpdate") */ public void setName(String name) { this.name = name; } /** * @@org.springframework.jmx.export.metadata.ManagedAttribute * (defaultValue="foo", persistPeriod=300) */ public String getName() { return name; } /** * @@org.springframework.jmx.export.metadata.ManagedOperation * (description="Add Two Numbers Together") */ public int add(int x, int y) { return x + y; } public void dontExposeMe() { throw new RuntimeException(); } }
여기서 당신은 JmxTestBean 클래스가 ManagedResource 속성으로 표시되고 이 ManagedResource 속성이 프라퍼티의 세트로 설정된다. 이러한 프라퍼티는 MBeanExporter에 의해 생성되는 MBean의 다양한 양상(aspect)로 설정하기 위해 사용될수 있고 Section 20.4.4, “소스레벨 메타데이타 타입들”에서 나중에 좀더 상세하게 설명된다.
당신은 ManagedAttribute속성으로 표시되는 age와 name속성들 모두 알릴것이지만 age 프라퍼티의 경우 오직 getter만이 표시된다. 이것은 속성처럼 관리 인터페이스내 포함되기 위한 이헌 프라퍼티 모두를 야기할것이다. 그리고 age속성은 읽기전용이다.
마지막으로 당신은 dontExposeMe() 메소드가 표시되지 않기 때문에 add(int, int)메소드가 ManagedOperation속성으로 표시된다는것을 알릴것이다. 이것은 MetadataMBeanInfoAssembler를 사용할때 오직 하나의 작업(operation)인 add(int, int)을 포함하기 위한 관리 인터페이스를 야기할것이다.
아래의 코드는 당신이 MetadataMBeanInfoAssembler를 사용하기 위한 MBeanExporter를 설정하는 방법을 보여준다.
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <map> <entry key="bean:name=testBean1" value-ref="testBean"/> </map> </property> <property name="assembler" ref="assembler"/> </bean> <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> <bean id="attributeSource" class="org.springframework.jmx.export.metadata.AttributesJmxAttributeSource"> <property name="attributes"> <bean class="org.springframework.metadata.commons.CommonsAttributes"/> </property> </bean> <bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler"> <property name="attributeSource" ref="attributeSource"/> </bean> </beans>
여기서 당신은 MetadataMBeanInfoAssembler bean이 AttributesJmxAttributeSource 클래스의 인스턴스로 설정되고 assembler프라퍼티를 통해 MBeanExporter로 전달되는것을 볼수 있다. 이것은 당신의 Spring-노출 MBean을 위한 데타데이타-기반 관리 인터페이스의 장점을 가져오기 위해 요구되는 모든것이다.
관리 인터페이스 정의를 위한 JDK 5.0 annotation의 사용을 가능하게 하기 위해 Spring은 그것들을 읽기 위해 MBeanInfoAssembler을 허용하는 Commons Attribute속성 클래스와 JmxAttributeSource전략 인터페이스의 구현물인 AnnotationsJmxAttributeSource를 반영하는 annotation의 세트를 제공한다.
밑의 예제는 관리 인터페이스가 정의된 JDK 5.0 annotation을 가진 bean을 보여준다.
package org.springframework.jmx; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.jmx.export.annotation.ManagedOperation; import org.springframework.jmx.export.annotation.ManagedAttribute; @ManagedResource(objectName="bean:name=testBean4", description="My Managed Bean", log=true, logFile="jmx.log", currencyTimeLimit=15, persistPolicy="OnUpdate", persistPeriod=200, persistLocation="foo", persistName="bar") public class AnnotationTestBean implements IJmxTestBean { private String name; private int age; @ManagedAttribute(description="The Age Attribute", currencyTimeLimit=15) public int getAge() { return age; } public void setAge(int age) { this.age = age; } @ManagedAttribute(description="The Name Attribute", currencyTimeLimit=20, defaultValue="bar", persistPolicy="OnUpdate") public void setName(String name) { this.name = name; } @ManagedAttribute(defaultValue="foo", persistPeriod=300) public String getName() { return name; } @ManagedOperation(description="Add two numbers") @ManagedOperationParameters({ @ManagedOperationParameter(name = "x", description = "The first number"), @ManagedOperationParameter(name = "y", description = "The second number")}) public int add(int x, int y) { return x + y; } public void dontExposeMe() { throw new RuntimeException(); } }
당신이 볼수 있는것처럼 메타데이타 정의의 기본적인 문법보다 조금 변경된것을 볼수 있다. 그 장면뒤에서 이 접근법은 JDK 5.0 annotation이 Commons Attributes에 의해 사용되는 클래스로 형변환되기 때문에 수행시 조금더 느리다. 어쨌든 이것은 한번에 한한(one-off) 비용이고 JDK 5.0 annotations은 당신에게 컴파일시각 체크(compile-time checking)의 이득을 부여한다.
위 주석처리된(annotated) 클래스를 위한 부수적인 XML설정은 아래에서 볼수 있다.
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="assembler" ref="assembler"/> <property name="namingStrategy" ref="namingStrategy"/> <property name="autodetect" value="true"/> </bean> <bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/> <!-- will create management interface using annotation metadata --> <bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler"> <property name="attributeSource" ref="jmxAttributeSource"/> </bean> <!-- will pick up ObjectName from annotation --> <bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy"> <property name="attributeSource" ref="jmxAttributeSource"/> </bean> <bean id="testBean" class="org.springframework.jmx.AnnotationTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> </beans>
다음의 소스레벨 메타데이타 타입들은 Spring JMX내에서 사용되기 위해 사용가능하다.
Table 20.2. 소스레벨 메타데이타 타입
목적 | Commons Attributes 속성 | JDK 5.0 Annotation | Attribute / Annotation 타입 |
---|---|---|---|
Class의 모든 인스턴스를 JMX관리 자원처럼 표시 | ManagedResource | @ManagedResource | Class |
메소드를 JMX작업처럼 표시하기 | ManagedOperation | @ManagedOperation | Method |
JMX속성의 반을 getter나 setter로 표시하기 | ManagedAttribute | @ManagedAttribute | Method (오직 getters 와 setters) |
작업 파라미터를 위한 상세설명 정의하기 | ManagedOperationParameter | @ManagedOperationParameter 와 @ManagedOperationParameters | Method |
다음의 설정 파라미터는 소스레벨 메타데이타 타입들의 사용을 위해 사용가능하다.
Table 20.3. 소스레벨 메타데이타 파라미터
파라미터 | 설명 | 적용 |
---|---|---|
objectName | 관리되는 자원의 ObjectName를 결정하기 위한 MetadataNamingStrategy에 의해 사용 | ManagedResource |
description | 자원, 속성 또는 작업(operation)의 친숙한 설명 셋팅하기 | ManagedResource, ManagedAttribute, ManagedOperation, ManagedOperationParameter |
currencyTimeLimit | currencyTimeLimit 서술자 필드의 값을 셋팅하기 | ManagedResource, ManagedAttribute |
defaultValue | defaultValue 서술자 필드의 값을 셋팅하기 | ManagedAttribute |
log | log 서술자 필드의 값을 셋팅하기 | ManagedResource |
logFile | logFile 서술자 필드의 값을 셋팅하기 | ManagedResource |
persistPolicy | persistPolicy 서술자 필드의 값을 셋팅하기 | ManagedResource |
persistPeriod | persistPeriod 서술자 필드의 값을 셋팅하기 | ManagedResource |
persistLocation | persistLocation 서술자 필드의 값을 셋팅하기 | ManagedResource |
persistName | persistName 서술자 필드의 값을 셋팅하기 | ManagedResource |
name | 작업(operation) 파라미터의 표시명(display name)을 셋팅하기 | ManagedOperationParameter |
index | 작업(operation) 파라미터의 인덱스 셋팅하기 | ManagedOperationParameter |
좀더 간단한 설정을 위해, Spring은 MBean자원의 자동감지를 위한 지원을 추가하는 MBeanInfoAssembler인터페이스를 확장하는 AutodetectCapableMBeanInfoAssembler인터페이스를 소개한다. 만약 당신이 AutodetectCapableMBeanInfoAssembler의 인스턴스를 사용해서 MBeanExporter을 설정한다면 이것은 JMX에 드러내기 위한 bean의 포함(inclusion)에 '결정(vote)'하는것을 허용한다.
특히, AutodetectCapableMBeanInfo 의 구현물만이 ManagedResource속성으로 표시되는 bean을 포함하기 위해 결정(vote)할 MetadataMBeanInfoAssembler이다. 이 경우 디폴트 접근법은 이것과 같은 설정의 결과를 보이는 ObjectName처럼 bean이름을 사용하는 것이다.
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <!-- notice how no 'beans' are explicitly configured here --> <property name="autodetect" value="true"/> <property name="assembler" ref="assembler"/> </bean> <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> <!-- (for Commons Attributes-based metadata) --> <bean id="attributeSource" class="org.springframework.jmx.export.metadata.AttributesJmxAttributeSource"> <property name="attributes"> <bean class="org.springframework.metadata.commons.CommonsAttributes"/> </property> </bean> <!-- (for Java5+ annotations-based metadata) --> <!-- <bean id="attributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/> --> <bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler"> <property name="attributeSource" ref="attributeSource"/> </bean> </beans>
이 설정내에서 MBeanExporter에 전달되는 bean은 없다. 어쨌든 JmxTestBean은 이것이 ManagedResource 속성으로 표시된 이후 등록될것이고 MetadataMBeanInfoAssembler는 이것을 감지하고 이것을 포함하기 위해 결정한다. 이 접근법이 가진 문제점은 JmxTestBean의 이름이 현재 비지니스 의미(meaning)를 가진다는것이다. 당신은 Section 20.5, “당신의 bean을 위한 ObjectName 제어하기”에서 정의되는것처럼 ObjectName 생성을 위한 디폴트 행위를 변경하여 이 문제를 해결할수 있다.
MetadataMBeanInfoAssembler에 추가적으로, Spring은 당신에게 인터페이스의 집합(collection)내 정의된 메소드의 세트에 기반하여 드러나는 메소드와 프라퍼티를 강요하는것을 허용하는 InterfaceBasedMBeanInfoAssembler을 포함한다.
비록 MBean을 드러내기 위한 표준적인 기법이 인터페이스와 간단한 명명 개요(scheme)를 사용하는 것이라고 하더라도 InterfaceBasedMBeanInfoAssembler는 당신에게 하나의 인터페이스보다 많은 수를 사용하는것을 허용하고 MBean인터페이스를 구현하는 당신의 bean을 위한 필요성을 제거하는 명명규칙을 위한 필요성을 제거하여 이 기능을 확장한다.
당신이 좀더 일찍 본 JmxTestBean클래스를 위한 관리 인터페이스를 정의하기 위해 사용되는 이 인터페이스를 보라.
public interface IJmxTestBean { public int add(int x, int y); public long myOperation(); public int getAge(); public void setAge(int age); public void setName(String name); public String getName(); }
이 인터페이스는 JMX MBean의 작업(operation)과 속성처럼 드러날 메소드와 프라퍼티를 정의한다. 밑의 코드는 관리 인터페이스를 위한 정의처럼 이 인터페이스를 사용하기 위해 Spring JMX를 설정하는 방법을 보여준다.
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <map> <entry key="bean:name=testBean5" value-ref="testBean"/> </map> </property> <property name="assembler"> <bean class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler"> <property name="managedInterfaces"> <value>org.springframework.jmx.IJmxTestBean</value> </property> </bean> </property> </bean> <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> </beans>
여기서 당신은 어느 bean을 위한 관리 인터페이스를 생성할때 InterfaceBasedMBeanInfoAssembler가 IJmxTestBean 인터페이스를 사용하기 위해 설정되는것을 볼수 있다. InterfaceBasedMBeanInfoAssembler에 의해 처리되는 bean이 JMX 관리 인터페이스를 생성하기 위해 사용되는 인터페이스를 구현하는것을 요구하지 않는 것을 이해하는것은 중요하다.
위 경우에, IJmxTestBean 인터페이스는 모든 bean을 위한 모든 관리 인터페이스를 생성하기 위해 사용된다. 많은 경우 이것은 바람직한 행위가 아니며 당신은 다른 bean을 위해 다른 인터페이스를 사용하길 원할것이다. 이 경우 당신은 각각의 항목의 key가 bean이름이고 각각의 항목의 값은 bean사용을 위한 인터페이스 이름의 콤마로 분리된 리스트인 interfaceMappings 을 통한 프라퍼티를 통해 Properties에 InterfaceBasedMBeanInfoAssembler을 전달할수 있다.
만약 managedInterfaces 나 interfaceMappings 프라퍼티를 통해 명시된 관리 인터페이스가 없다면 InterfaceBasedMBeanInfoAssembler는 bean에 반영할것이고 관리 인터페이스를 생성하기 위한 bean에 의해 구현되는 모든 인터페이스를 사용할것이다.
MethodNameBasedMBeanInfoAssembler는 당신에게 속성과 작업(operation)처럼 JMX에 드러날 메소드명의 리스트를 명시하는것을 허용한다. 밑의 코드는 이것을 위한 샘플 설정을 보여준다.
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <map> <entry key="bean:name=testBean5" value-ref="testBean"/> </map> </property> <property name="assembler"> <bean class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler"> <property name="managedMethods"> <value>add,myOperation,getName,setName,getAge</value> </property> </bean> </property> </bean>
여기서 당신은 add 와 myOperation 메소드가 JMX작업(operation)처럼 드러나고 getName(), setName(String) 그리고 getAge() 메소드가 선호되는 JMX속성의 절반처럼 드러날것을 볼수 있다. 위 코드에서 메소드 맵핑은 JMX에 드러나는 bean에 적용한다. bean대 bean이라는 기본이 드러나는 메소드를 제어하는 것은 메소드명의 리스트에 bean이름을 맵핑하기 위한 MethodNameMBeanInfoAssembler의 methodMappings프라퍼티를 사용한다.
MBeanExporter는 이것이 등록하는 각각의 bean을 위한 ObjectName를 얻기 위해 ObjectNamingStrategy의 구현물로 위임한다. 디폴트 구현물인 KeyNamingStrategy는 디폴트에 의해 ObjectName처럼 beans Map의 key를 사용할것이다. 추가적으로 KeyNamingStrategy는 ObjectName을 분석하기 위한 Properties 파일내 항목에 beans Map의 key를 맵핑할수 있다. KeyNamingStrategy에 추가적으로, Spring은 두가지 추가적인 ObjectNamingStrategy구현물(bean의 JVM확인에 기반하는 ObjectName을 빌드하는 IdentityNamingStrategy와 ObjectName를 얻기 위해 소스레벨 메타데이타를 사용하는 MetadataNamingStrategy)을 제공한다.
당신은 당신 자신의 KeyNamingStrategy 인스턴스를 설정할수 있고 bean key를 사용하는것보다 Properties 인스턴스로부터 ObjectName를 읽어서 이것을 설정한다. KeyNamingStrategy는 bean key에 대응하는 key를 가진 Properties내 항목을 위치시키는 시도를 할것이다. 만약 어떠한 항목이 발견되지 않거나 Properties 인스턴스가 null이라면 그 bean key는 자체적으로 사용된다.
밑의 코드는 KeyNamingStrategy를 위한 샘플 설정을 보여준다.
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <map> <entry key="testBean" value-ref="testBean"/> </map> </property> <property name="namingStrategy" ref="namingStrategy"/> </bean> <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> <bean id="namingStrategy" class="org.springframework.jmx.export.naming.KeyNamingStrategy"> <property name="mappings"> <props> <prop key="testBean">bean:name=testBean1</prop> </props> </property> <property name="mappingLocations"> <value>names1.properties,names2.properties</value> </property> </bean </beans>
여기서 KeyNamingStrategy의 인스턴스는 mapping프라퍼티에 의해 정의된 Properties 인스턴스로 부터 병합된 Properties 인스턴스와 mapping 프라퍼티에 의해 정의된 경로내 위치한 프라퍼티 파일들로 설정된다. 이 설정에서 testBean bean은 이 항목이 bean key에 대응되는 key를 가진 Properties 인스턴스내 항목이 된 이후 ObjectName bean:name=testBean1가 주어질것이다.
Properties 인스턴스내 발견될수 있는 항목이 없다면 bean key명은 ObjectName처럼 사용된다.
MetadataNamingStrategy 는 ObjectName을 생성하기 위한 각각의 bean의 ManagedResource속성의 objectName프라퍼티를 사용한다. 밑의 코드는 MetadataNamingStrategy를 위한 설정을 보여준다.
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <map> <entry key="testBean" value-ref="testBean"/> </map> </property> <property name="namingStrategy" ref="namingStrategy"/> </bean> <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> <bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy"> <property name="attributeSource" ref="attributeSource"/> </bean> <bean id="attributeSource" class="org.springframework.jmx.export.metadata.AttributesJmxAttributeSource"/> </beans>
원격 접속을 위해 Spring JMX 모듈은 서버측과 클라이언트측 연결자를 생성하기 위한 org.springframework.jmx.support패키지내 두가지의 FactoryBean 구현물을 제공한다.
Spring JMX가 JSR-160 JMXConnectorServer를 생성, 시작 그리고 드러내기 위해 다음의 설정을 사용한다.
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean"/>
디폴트에 의해 ConnectorServerFactoryBean은 "service:jmx:jmxmp://localhost:9875"를 바운드하는 JMXConnectorServer를 생성한다. serverConnector bean은 로컬호스트, 9875포트의 JMXMP 프로토콜을 통해 클라이언트로 로컬 MBeanServer를 드러낸다. JMXMP 프로토콜은 JSR 160 스펙에 의해 선택적으로 표시된다는것을 알라. 현재 인기있는 오픈소스 구현물인 MX4J와 JMXMP를 지원하지 않는 자바 5.0에 의해 제공되는 것이다.
다른 URL을 명시하고 MBeanServer를 가진 JMXConnectorServer를 등록하는 것은 serviceUrl 과 objectName 프라퍼티를 사용한다.
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean"> <property name="objectName" value="connector:name=rmi"/> <property name="serviceUrl" value="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/myconnector"/> </bean>
만약 objectName 프라퍼티가 셋팅된다면 Spring은 ObjectName하위의 MBeanServer으로 당신의 연결자를 자동적으로 등록할것이다. 밑의 예제는 당신이 JMXConnector를 생성할때 ConnectorServerFactoryBean로 전달할수 있는 파라미터의 전체 세트를 보여준다.
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean"> <property name="objectName" value="connector:name=iiop"/> <property name="serviceUrl" value="service:jmx:iiop://localhost/jndi/iiop://localhost:900/myconnector"/> <property name="threaded" value="true"/> <property name="daemon" value="true"/> <property name="environment"> <map> <entry key="someKey" value="someValue"/> </map> </property> </bean>
RMI기반 connector를 사용할때, 당신은 명명등록을 위해 시작하는 서비스를 룩업할 필요가 있다(스스로이거나 rmiregistry). 만약 당신이 RMI를 통해 당신을 위한 원격 서비스를 내보내기 위해 Spring을 사용한다면, Spring은 RMI registry를 생성할것이다. 그렇지 않다면, 당신은 다음의 설정조각을 사용하여 registry를 쉽게 시작할수 있다.
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"> <property name="port" value="1099"/> </bean>
MBeanServer을 가능하게 하는 원격 JSR-160을 위해 MBeanServerConnection을 생성하는 것은 밑에서 보여지는것처럼 MBeanServerConnectionFactoryBean을 사용한다.
<bean id="clientConnector" class="org.springframework.jmx.support.MBeanServerConnectionFactoryBean"> <property name="serviceUrl" value="service:jmx:rmi://localhost:9875"/> </bean>
JSR-160 은 클라이언트와 서버간에 이루어지는 통신의 방법을 위한 확장을 허락한다. 위 예제는 JSR-160(IIOP 와 JRMP) 와 선택적인 JMXMP에 의해 요구되는 필수 RMI-기반의 구현물을 사용하는것이다. 다른 제공자(provider)와 JMX구현물(MX4J와 같은)을 사용하여 당신은 SOAP, Hessian, 간단한 HTTP나 SSL곳곳의 Burlap, 그리고 다른것들같은 프로토콜의 장점을 가질수 있다.
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean"> <property name="objectName" value="connector:name=burlap"/> <property name="serviceUrl" value="service:jmx:burlap://localhost:9874"/> </bean>
위 예제의 경우, MX4J 3.0.0이 사용되었다.좀더 다양한 정보를 위해서는 MX4J문서를 보라.
Spring JMX는 당신에게 로컬또는 원격 MBeanServer내 등록된 MBean에 대한 호출 경로를 재정의하는 프록시를 생성하는것을 허용한다. 이러한 프록시는 당신에게 당신의 MBean과 상호작용할수 있는 것을 통해 표준적인 자바 인터페이스를 제공한다. 밑의 코드는 로컬 MBeanServer내에서 실행중인 MBean을 위한 프록시를 설정하는 방법을 보여준다.
bean id="proxy" class="org.springframework.jmx.access.MBeanProxyFactoryBean"> <property name="objectName" value="bean:name=testBean"/> <property name="proxyInterface" value="org.springframework.jmx.IJmxTestBean"/> </bean>
여기서 당신은 프록시가 ObjectName(bean:name=testBean)하위에 등록된 MBean을 위해 생성되는것을 볼수 있다. 프록시가 구현할 인터페이스의 세트는 proxyInterfaces 프라퍼티에 의해 제어되고 MBean의 작업(operation)과 속성을 위한 인터페이스의 메소드와 프라퍼티를 맵핑하기 위한 규칙은 InterfaceBasedMBeanInfoAssembler에 의해 사용되는 규칙과 같다.
MBeanProxyFactoryBean은 MBeanServerConnection을 통해 접근가능한 MBean을 위한 프록시를 생성할수 있다. 디폴트에 의해 로컬 MBeanServer는 위치되고 사용되지만 당신은 이것을 오버라이드 할수 있고 원격 MBean을 위한 프록시 지점(pointing)을 위해 허용하는 원격 MBeanServer를 위한 MBeanServerConnection 지점(pointing)을 제공할수 있다.
<bean id="clientConnector" class="org.springframework.jmx.support.MBeanServerConnectionFactoryBean"> <property name="serviceUrl" value="service:jmx:rmi://remotehost:9875"/> </bean> <bean id="proxy" class="org.springframework.jmx.access.MBeanProxyFactoryBean"> <property name="objectName" value="bean:name=testBean"/> <property name="proxyInterface" value="org.springframework.jmx.IJmxTestBean"/> <property name="server" ref="clientConnector"/> </bean>
여기서 당신은 우리가 MBeanServerConnectionFactoryBean을 사용하여 원격 머신을 위한 MBeanServerConnection 지점을 생성하는것을 볼수 있다. 이 MBeanServerConnection은 server 프라퍼티를 통해 MBeanProxyFactoryBean으로 전달된다. 생성된 프록시는 MBeanServerConnection를 통해 MBeanServer로 모든 호출을 전달할것이다.
Spring의 JMX는 JMX통지를 위한 포괄적인 지원을 포함한다.
Spring의 JMX지원은 많은 MBeans을 가지는 많은 수의 NotificationListeners를 등록하는 것을 쉽게 만든다(이것은 Spring의 MBeanExporter에 의해 나오는 MBeans와 몇몇 다른 기법을 통해 등록된 MBeans를 포함한다). 예제는 NotificationListeners의 등록에 영향을 주는 간단한 방법을 잘 보여줄것이다. 각각 그리고 항상 대상 MBean변경의 속성을 알리고자(Notification를 통해) 하는 시나리오를 생각해보자.
package com.example; import javax.management.AttributeChangeNotification; import javax.management.Notification; import javax.management.NotificationFilter; import javax.management.NotificationListener; public class ConsoleLoggingNotificationListener implements NotificationListener, NotificationFilter { public void handleNotification(Notification notification, Object handback) { System.out.println(notification); System.out.println(handback); } public boolean isNotificationEnabled(Notification notification) { return AttributeChangeNotification.class.isAssignableFrom(notification.getClass()); } }
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <map> <entry key="bean:name=testBean1" value-ref="testBean"/> </map> </property> <property name="notificationListenerMappings"> <map> <entry key="bean:name=testBean1"> <bean class="com.example.ConsoleLoggingNotificationListener"/> </entry> </map> </property> </bean> <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> </beans>
위 설정에서, 항상 JMX Notification은 대상 MBean(bean:name=testBean1)으로부터 퍼트려진다. notificationListenerMappings 프라퍼티를 통해 리스너로 등록된 ConsoleLoggingNotificationListener bean은 통지될것이다. ConsoleLoggingNotificationListener bean은 Notification에 적절하게 응답하는 액션이 무엇이든 가질수 있다.
둘러싸는 MBeanExporter가 보내는 모든 bean을 위한 하나의 NotificationListener 인스턴스를 등록하길 원한다면, notificationListenerMappings 프라퍼티 맵내 항목을 위한 key로 특별한 와일드카드 '*'를 사용할수 있다.
<property name="notificationListenerMappings"> <map> <entry key="*"> <bean class="com.example.ConsoleLoggingNotificationListener"/> </entry> </map> </property>
반대로 할 필요가 있다면(이를테면, MBean에 대해 많은 수의 구별되는 리스너를 등록한다면), 대신 notificationListeners 리스트 프라퍼티를 사용해야만 한다(그리고 notificationListenerMappings 프라퍼티 보다는 오히려). 하나의 MBean을 위한 NotificationListener를 설정하는 대신, NotificationListenerBean 인스턴스를 설정한다. NotificationListenerBean은 MBeanServer에 대해 등록되기 위한 NotificationListener 와 ObjectName(또는 ObjectNames)를 캡슐화한다. NotificationListenerBean는 NotificationFilter와 고급 JMX통지 시나리오에서 사용될수 있는 임의의 handback객체 같은 다른 많은 프라퍼티를 캡슐화한다.
NotificationListenerBean 인스턴스를 사용할때 설정은 이전에 존재하는 것과 무턱대고 다르지 않다.
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <map> <entry key="bean:name=testBean1" value-ref="testBean"/> </map> </property> <property name="notificationListeners"> <list> <bean class="org.springframework.jmx.export.NotificationListenerBean"> <constructor-arg> <bean class="com.example.ConsoleLoggingNotificationListener"/> </constructor-arg> <property name="mappedObjectNames"> <list> <bean class="javax.management.ObjectName"> <constructor-arg value="bean:name=testBean1"/> </bean> </list> </property> </bean> </list> </property> </bean> <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> </beans>
위 예제는 첫번째 통지 예제와 동등하다. Notification이 발생할때마다 handback객체가 주어지길 원하고 추가적으로 우리는 NotificationFilter를 제공하여 관계없는 Notifications을 걸러내길 원한다고 가정해보자. (handback객체가 무엇인지, 그리고 NotificationFilter가 무엇인지에 대해 완전한 정보를 원한다면, 'JMX 통지 모델'이라는 JMX스펙(1.2) 부분을 보라).
<beans> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <map> <entry key="bean:name=testBean1" value-ref="testBean1"/> <entry key="bean:name=testBean2" value-ref="testBean2"/> </map> </property> <property name="notificationListeners"> <list> <bean class="org.springframework.jmx.export.NotificationListenerBean"> <constructor-arg ref="customerNotificationListener"/> <property name="mappedObjectNames"> <list> <!-- let's handle notifications from two distinct MBeans --> <bean class="javax.management.ObjectName"> <constructor-arg value="bean:name=testBean1"/> </bean> <bean class="javax.management.ObjectName"> <constructor-arg value="bean:name=testBean2"/> </bean> </list> </property> <property name="handback"> <bean class="java.lang.String"> <constructor-arg value="This could be anything..."/> </bean> </property> <property name="notificationFilter" ref="customerNotificationListener"/> </bean> </list> </property> </bean> <!-- implements both the 'NotificationListener' and 'NotificationFilter' interfaces --> <bean id="customerNotificationListener" class="com.example.ConsoleLoggingNotificationListener"/> <bean id="testBean1" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="TEST"/> <property name="age" value="100"/> </bean> <bean id="testBean2" class="org.springframework.jmx.JmxTestBean"> <property name="name" value="ANOTHER TEST"/> <property name="age" value="200"/> </bean> </beans>
Spring은 Notifications을 받는 것을 등록할뿐 아니라 Notifications을 발행하는 지원을 제공한다.
![]() | Note |
---|---|
이 부분은 MBeanExporter를 통해 MBean으로 나타나는 Spring관리 bean에만 관계된다. 존재하고 사용자 정의 MBean은 통지 발행을 위한 표준 JMX API를 사용할것이다. |
Spring의 JMX 통지 발행지원내 핵심 인터페이스는 NotificationPublisher(org.springframework.jmx.export.notification 패키지에서 정의되는)인터페이스이다. MBeanExporter 인스턴스를 통해 MBean으로 나타날 bean은 NotificationPublisher 인스턴스에 접근하기 위한 관련 NotificationPublisherAware 인터페이스를 구현할수 있다. NotificationPublisherAware 인터페이스는 Notifications를 발행하기 위해 사용할수 있는 bean을 말하는 간단한 setter메소드를 통해 bean을 구현하는 NotificationPublisher의 인스턴스를 간단히 제공한다.
NotificationPublisher클래스를 위한 Javadoc내 상태처럼, NotificationPublisher 기법을 통해 이벤트를 발행하는 관리 bean은 어느 통지 리스너의 상태 관리를 책임지지 않는다. Spring의 JMX지원은 모든 JMX구조적인 이슈를 다룰것이다. 애플리케이션 개발자처럼 할 필요가 있는 모든것은 NotificationPublisherAware인터페이스를 구현하고 제공되는 NotificationPublisher 인스턴스를 사용하여 이벤트를 발행하는것을 시작한다. NotificationPublisher는 관리 bean이 MBeanServer로 등록된 후에 셋팅될것이다.
NotificationPublisher 인스턴스를 사용하는 것은 매우 일관적이다. JMX Notification 인스턴스(또는 적절한 Notification 하위클래스의 인스턴스)를 간단히 생성한다. 이것은 발행되기 위한 이벤트에 적절한 데이터로 통지하는 것을 활성화한다. 그리고 Notification를 전달하는 NotificationPublisher인스턴스에서 sendNotification(Notification)를 호출한다.
간단한 예제를 보자. 이 시나리오에서, JmxTestBean의 인스턴스는 add(int, int)작업이 호출될때마다 NotificationEvent를 발행할것이다.
package org.springframework.jmx;
import org.springframework.jmx.export.notification.NotificationPublisherAware;
import org.springframework.jmx.export.notification.NotificationPublisher;
import javax.management.Notification;
public class JmxTestBean implements IJmxTestBean, NotificationPublisherAware {
private String name;
private int age;
private boolean isSuperman;
private NotificationPublisher publisher;
// other getters and setters omitted for clarity
public int add(int x, int y) {
int answer = x + y;
this.publisher.sendNotification(new Notification("add", this, 0));
return answer;
}
public void dontExposeMe() {
throw new RuntimeException();
}
public void setNotificationPublisher(NotificationPublisher notificationPublisher) {
this.publisher = notificationPublisher;
}
}
NotificationPublisher 인터페이스와 작업하는 부수적인 장치는 Spring의 JMX지원의 좋은 기능중 하나이다. 이것은 Spring과 JMX모두를 위해 당신의 클래스를 커플링의 price태그가 딸려나온다. 여기 advice는 실용적이다. 만약 당신이 NotificationPublisher에 의해 제공되는 기능이 필요하고 Spring과 JMX모두를 커플링하는 것을 받아들일수 있다면, 그렇게 하라.
이 부분은 JMX에 대한 더 많은 자원에 대한 링크를 포함한다.
Sun의 JMX 홈페이지
JMX 스펙 (JSR-000003)
JMX Remote API 스펙 (JSR-000160)
MX4J 홈페이지 (다양한 JMX스펙의 오픈소스 구현물)
JMX로 시작하기 - Sun의 소개글