Loading...
Spring Framework Reference Documentation 7.0.2의 Exporting Your Beans to JMX의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
Spring의 JMX 프레임워크에서 핵심 클래스는 MBeanExporter입니다. 이 클래스는
당신의 Spring 빈을 가져와 JMX MBeanServer에 등록하는 역할을 합니다.
예를 들어, 다음 클래스를 고려해 보십시오:
1public class JmxTestBean implements IJmxTestBean { 2 3 private String name; 4 private int age; 5 6 @Override 7 public int getAge() { 8 return age; 9 } 10 11 @Override 12 public void setAge(int age) { 13 this.age = age; 14 } 15 16 @Override 17 public void setName(String name) { 18 this.name = name; 19 } 20 21 @Override 22 public String getName() { 23 return name; 24 } 25 26 @Override 27 public int add(int x, int y) { 28 return x + y; 29 } 30 31 @Override 32 public void dontExposeMe() { 33 throw new RuntimeException(); 34 } 35}
1class JmxTestBean : IJmxTestBean { 2 3 override lateinit var name: String 4 override var age = 0 5 6 override fun add(x: Int, y: Int): Int { 7 return x + y 8 } 9 10 override fun dontExposeMe() { 11 throw RuntimeException() 12 } 13}
이 빈의 프로퍼티와 메서드를 MBean의 애트리뷰트와 오퍼레이션으로 노출하려면,
설정 파일에서 MBeanExporter 클래스의 인스턴스를 설정하고
다음 예제에서 보이는 것처럼 빈을 전달하면 됩니다:
1@Configuration 2public class JmxConfiguration { 3 4 @Bean 5 MBeanExporter exporter(JmxTestBean testBean) { 6 MBeanExporter exporter = new MBeanExporter(); 7 exporter.setBeans(Map.of("bean:name=testBean1", testBean)); 8 return exporter; 9 } 10 11 @Bean 12 JmxTestBean testBean() { 13 JmxTestBean testBean = new JmxTestBean(); 14 testBean.setName("TEST"); 15 testBean.setAge(100); 16 return testBean; 17 } 18}
1@Configuration 2class JmxConfiguration { 3 4 @Bean 5 fun exporter(testBean: JmxTestBean) = MBeanExporter().apply { 6 setBeans(mapOf("bean:name=testBean1" to testBean)) 7 } 8 9 @Bean 10 fun testBean() = JmxTestBean().apply { 11 name = "TEST" 12 age = 100 13 } 14}
1<beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://www.springframework.org/schema/beans 4 https://www.springframework.org/schema/beans/spring-beans.xsd"> 5 6 <!-- this bean must not be lazily initialized if the exporting is to happen --> 7 <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> 8 <property name="beans"> 9 <map> 10 <entry key="bean:name=testBean1" value-ref="testBean"/> 11 </map> 12 </property> 13 </bean> 14 15 <bean id="testBean" class="org.example.JmxTestBean"> 16 <property name="name" value="TEST"/> 17 <property name="age" value="100"/> 18 </bean> 19</beans>
앞선 설정 스니펫에서 관련된 빈 정의는 exporter
빈입니다. beans 프로퍼티는 MBeanExporter에게 어떤 빈이 JMX MBeanServer로
export 되어야 하는지 정확히 알려줍니다. 기본 설정에서, beans Map의 각 엔트리의 key는
해당 엔트리 value가 참조하는 빈의 ObjectName으로 사용됩니다.
이 동작은
Controlling ObjectName Instances for Your Beans에 설명된 대로 변경할 수 있습니다.
이 설정으로, testBean 빈은 ObjectName bean:name=testBean1 아래의
MBean으로 노출됩니다. 기본적으로, 빈의 모든 public 프로퍼티는 애트리뷰트로
노출되고, 모든 public 메서드(Object 클래스로부터 상속된 메서드는 제외)는
오퍼레이션으로 노출됩니다.
MBeanExporter는Lifecycle빈입니다( Startup and Shutdown Callbacks를 참조하십시오). 기본적으로, MBean은 애플리케이션 라이프사이클 동안 가능한 한 늦게 export 됩니다. export가 발생하는phase를 설정하거나,autoStartup플래그를 설정하여 자동 등록을 비활성화할 수 있습니다.
앞선 section에 표시된 설정은
애플리케이션이 이미 하나(그리고 오직 하나)의 MBeanServer가 실행 중인 환경에서
실행되고 있다고 가정합니다. 이 경우, Spring은 실행 중인 MBeanServer를 찾고
(있다면) 해당 서버에 빈을 등록하려고 시도합니다.
이 동작은
애플리케이션이 자체 MBeanServer를 가진 컨테이너(Tomcat이나 IBM WebSphere 등) 내부에서
실행될 때 유용합니다.
그러나 이 방식은 standalone 환경이나 MBeanServer를 제공하지 않는 컨테이너 내부에서
실행될 때는 아무런 도움이 되지 않습니다. 이를 해결하기 위해,
설정에 org.springframework.jmx.support.MBeanServerFactoryBean 클래스의
인스턴스를 추가하여 선언적으로 MBeanServer 인스턴스를 생성할 수 있습니다.
또한, MBeanExporter 인스턴스의 server 프로퍼티 값을
MBeanServerFactoryBean이 반환한 MBeanServer 값으로 설정하여
특정 MBeanServer가 사용되도록 보장할 수 있습니다. 다음 예제에서 보이는 것처럼
할 수 있습니다:
1<beans> 2 3 <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/> 4 5 <!-- 6 this bean needs to be eagerly pre-instantiated in order for the exporting to occur; 7 this means that it must not be marked as lazily initialized 8 --> 9 <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> 10 <property name="beans"> 11 <map> 12 <entry key="bean:name=testBean1" value-ref="testBean"/> 13 </map> 14 </property> 15 <property name="server" ref="mbeanServer"/> 16 </bean> 17 18 <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> 19 <property name="name" value="TEST"/> 20 <property name="age" value="100"/> 21 </bean> 22 23</beans>
앞선 예제에서, MBeanServer 인스턴스는 MBeanServerFactoryBean에 의해 생성되고
server 프로퍼티를 통해 MBeanExporter에 제공됩니다. 자체 MBeanServer
인스턴스를 제공하면, MBeanExporter는 실행 중인 MBeanServer를 찾으려 하지 않고
제공된 MBeanServer 인스턴스를 사용합니다.
이것이 올바르게 동작하려면 classpath에 JMX 구현이 있어야 합니다.
MBeanServer서버가 지정되지 않은 경우, MBeanExporter는 실행 중인 MBeanServer를 자동으로
감지하려고 시도합니다. 이는 하나의 MBeanServer 인스턴스만 사용되는 대부분의
환경에서 동작합니다.
그러나 여러 인스턴스가 존재할 때는 exporter가 잘못된
서버를 선택할 수 있습니다. 이런 경우, 다음 예제에서 보이는 것처럼
MBeanServer agentId를 사용하여 어떤 인스턴스가 사용되어야 하는지
지정해야 합니다:
1<beans> 2 <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"> 3 <!-- indicate to first look for a server --> 4 <property name="locateExistingServerIfPossible" value="true"/> 5 <!-- search for the MBeanServer instance with the given agentId --> 6 <property name="agentId" value="MBeanServer_instance_agentId>"/> 7 </bean> 8 <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> 9 <property name="server" ref="mbeanServer"/> 10 ... 11 </bean> 12</beans>
기존 MBeanServer의 agentId가 lookup 메서드를 통해 검색되는 동적(또는 알 수 없는)
값인 플랫폼이나 경우에는,
다음 예제에서 보이는 것처럼
factory-method를
사용해야 합니다:
1<beans> 2 <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> 3 <property name="server"> 4 <!-- Custom MBeanServerLocator --> 5 <bean class="platform.package.MBeanServerLocator" factory-method="locateMBeanServer"/> 6 </property> 7 </bean> 8 9 <!-- other beans here --> 10 11</beans>
MBeanExporter로 설정된 빈이 lazy initialization으로도 설정되어
있다면, MBeanExporter는 이 계약을 깨지 않고 빈의 인스턴스를 생성하는 것을
피합니다. 대신, MBeanServer에 프록시를 등록하고 프록시에 대한 첫 호출이
발생할 때까지 컨테이너로부터 빈을 얻는 것을 지연시킵니다.
이는 또한 FactoryBean resolution에도 영향을 미치며, 이때 MBeanExporter는
정기적으로 생성된 객체를 인트로스펙트하여 사실상 FactoryBean.getObject()를
트리거 합니다. 이를 피하기 위해, 해당 빈 정의를 lazy-init으로
mark 하십시오.
MBeanExporter를 통해 export 되고 이미 유효한 MBean인 모든 빈은
Spring의 추가적인 개입 없이 있는 그대로 MBeanServer에 등록됩니다.
다음 예제에서 보이는 것처럼, autodetect 프로퍼티를 true로 설정하여
MBeanExporter에 의해 MBean이 자동으로 감지되도록 할 수 있습니다:
1<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> 2 <property name="autodetect" value="true"/> 3</bean> 4 5<bean name="spring:mbean=true" class="org.springframework.jmx.export.TestDynamicMBean"/>
앞선 예제에서, spring:mbean=true라는 이름의 빈은 이미 유효한 JMX MBean이며
Spring에 의해 자동으로 등록됩니다. 기본적으로, JMX 등록을 위해
autodetect 된 빈은 그 빈 name이 ObjectName으로 사용됩니다.
이 동작은
Controlling ObjectName Instances for Your Beans에
상세히 설명된 대로 override 할 수 있습니다.
Spring MBeanExporter가 ObjectName bean:name=testBean1을 사용하여
MBeanServer에 MBean을 등록하려고 시도하는 시나리오를 고려해 보십시오.
이미 동일한 ObjectName 아래에 등록된 MBean 인스턴스가 있다면,
기본 동작은 실패(그리고 InstanceAlreadyExistsException을 throw)하는 것입니다.
MBean이 MBeanServer에 등록될 때 정확히 어떤 일이 발생하는지
제어할 수 있습니다. Spring의 JMX support는 등록 프로세스가 동일한
ObjectName 아래에 이미 등록된 MBean을 발견했을 때
등록 동작을 제어하기 위한 세 가지 서로 다른 registration behavior를
제공합니다.
다음 표는 이러한 registration behavior를 요약한 것입니다:
| Registration behavior | Explanation |
|---|---|
FAIL_ON_EXISTING | 이것은 기본 registration behavior입니다. 동일한 ObjectName 아래에 이미 MBean 인스턴스가 등록되어 있으면, 등록 중인 MBean은 등록되지 않고 InstanceAlreadyExistsException이 throw 됩니다. 기존의 MBean은 영향을 받지 않습니다. |
IGNORE_EXISTING | 동일한 ObjectName 아래에 이미 MBean 인스턴스가 등록되어 있으면, 등록 중인 MBean은 등록되지 않습니다. 기존 MBean은 영향을 받지 않으며, 어떤 Exception도 throw 되지 않습니다. 이는 여러 애플리케이션이 공유 MBeanServer에서 공통 MBean을 공유하고자 하는 환경에서 유용합니다. |
REPLACE_EXISTING | 동일한 ObjectName 아래에 이미 MBean 인스턴스가 등록되어 있으면, 이전에 등록되어 있던 기존 MBean은 unregistration 되고, 새로운 MBean이 그 자리에 등록됩니다(새 MBean이 사실상 이전 인스턴스를 대체합니다). |
Table 1. Registration Behaviors
앞선 표의 값은 RegistrationPolicy 클래스의 enum으로 정의되어 있습니다.
기본 registration behavior를 변경하려면, MBeanExporter 정의의
registrationPolicy 프로퍼티 값을 이들 값 중 하나로 설정해야 합니다.
다음 예제는 기본 registration behavior에서
REPLACE_EXISTING behavior로 변경하는 방법을 보여 줍니다:
1<beans> 2 3 <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> 4 <property name="beans"> 5 <map> 6 <entry key="bean:name=testBean1" value-ref="testBean"/> 7 </map> 8 </property> 9 <property name="registrationPolicy" value="REPLACE_EXISTING"/> 10 </bean> 11 12 <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> 13 <property name="name" value="TEST"/> 14 <property name="age" value="100"/> 15 </bean> 16 17</beans>
JMX
Controlling the Management Interface of Your Beans