Loading...
Spring Framework Reference Documentation 7.0.2의 Notifications의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
Spring의 JMX offering에는 JMX notifications에 대한 포괄적인 support가 포함되어 있습니다.
Spring의 JMX support는 어떤 수의 MBeans(여기에는 Spring의 MBeanExporter에 의해 export된 MBean과 다른 메커니즘을 통해 등록된 MBean이 포함됨)에 대해 어떤 수의 NotificationListeners도 쉽게 등록할 수 있게 해 줍니다. 예를 들어, target MBean의 attribute가 변경될 때마다(각각 매번) Notification을 통해 통지를 받고자 하는 시나리오를 생각해 보십시오.
다음 예제는 notifications를 콘솔에 기록합니다:
1package com.example; 2 3import javax.management.AttributeChangeNotification; 4import javax.management.Notification; 5import javax.management.NotificationFilter; 6import javax.management.NotificationListener; 7 8public class ConsoleLoggingNotificationListener 9 implements NotificationListener, NotificationFilter { 10 11 public void handleNotification(Notification notification, Object handback) { 12 System.out.println(notification); 13 System.out.println(handback); 14 } 15 16 public boolean isNotificationEnabled(Notification notification) { 17 return AttributeChangeNotification.class.isAssignableFrom(notification.getClass()); 18 } 19 20}
다음 예제는 notificationListenerMappings에 앞의 예제에서 정의한 ConsoleLoggingNotificationListener를 추가합니다:
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="notificationListenerMappings"> 10 <map> 11 <entry key="bean:name=testBean1"> 12 <bean class="com.example.ConsoleLoggingNotificationListener"/> 13 </entry> 14 </map> 15 </property> 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>
위의 설정이 설정되면, target MBean(bean:name=testBean1)에서 JMX Notification이 broadcast될 때마다 notificationListenerMappings 프로퍼티를 통해 리스너로 등록된 ConsoleLoggingNotificationListener 빈이 통지를 받습니다. 그 후 ConsoleLoggingNotificationListener 빈은 Notification에 대한 응답으로 적절하다고 판단되는 어떤 액션이든 취할 수 있습니다.
다음 예제에서 보듯이, export된 빈과 리스너 사이의 연결 고리로서 단순한 빈 이름을 사용할 수도 있습니다:
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="notificationListenerMappings"> 10 <map> 11 <entry key="testBean"> 12 <bean class="com.example.ConsoleLoggingNotificationListener"/> 13 </entry> 14 </map> 15 </property> 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>
enclosing MBeanExporter가 export하는 모든 빈에 대해 단일 NotificationListener 인스턴스를 등록하려면, 다음 예제에서 보듯이 notificationListenerMappings 프로퍼티 맵의 entry에 대한 key로 special wildcard(*)를 사용할 수 있습니다:
1<property name="notificationListenerMappings"> 2 <map> 3 <entry key="*"> 4 <bean class="com.example.ConsoleLoggingNotificationListener"/> 5 </entry> 6 </map> 7</property>
반대로(즉, 하나의 MBean에 대해 여러 개의 서로 다른 리스너를 등록해야 하는 경우) 해야 한다면, 대신 notificationListenerMappings 프로퍼티보다 notificationListeners 리스트 프로퍼티를 사용해야 합니다. 이번에는 단일 MBean에 대해 NotificationListener를 구성하는 대신, NotificationListenerBean 인스턴스를 구성합니다.
NotificationListenerBean은 NotificationListener와, 그것이 MBeanServer 내에서 등록될 ObjectName(또는 ObjectNames)을 캡슐화합니다. NotificationListenerBean은 또한 고급 JMX notification 시나리오에서 사용할 수 있는 NotificationFilter 및 임의의 handback 객체와 같은 여러 다른 프로퍼티도 캡슐화합니다.
다음 예제에서 보듯이, NotificationListenerBean 인스턴스를 사용할 때의 설정은 이전에 제시한 것과 크게 다르지 않습니다:
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="notificationListeners"> 10 <list> 11 <bean class="org.springframework.jmx.export.NotificationListenerBean"> 12 <constructor-arg> 13 <bean class="com.example.ConsoleLoggingNotificationListener"/> 14 </constructor-arg> 15 <property name="mappedObjectNames"> 16 <list> 17 <value>bean:name=testBean1</value> 18 </list> 19 </property> 20 </bean> 21 </list> 22 </property> 23 </bean> 24 25 <bean id="testBean" class="org.springframework.jmx.JmxTestBean"> 26 <property name="name" value="TEST"/> 27 <property name="age" value="100"/> 28 </bean> 29 30</beans>
위의 예제는 첫 번째 notification 예제와 동등합니다. 이제, Notification이 발생할 때마다 handback 객체를 전달받고자 하며, 또한 NotificationFilter를 제공하여 불필요한 Notifications를 걸러내고자 한다고 가정해 봅시다.
다음 예제는 이러한 목표를 달성합니다:
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="testBean1"/> 7 <entry key="bean:name=testBean2" value-ref="testBean2"/> 8 </map> 9 </property> 10 <property name="notificationListeners"> 11 <list> 12 <bean class="org.springframework.jmx.export.NotificationListenerBean"> 13 <constructor-arg ref="customerNotificationListener"/> 14 <property name="mappedObjectNames"> 15 <list> 16 <!-- handles notifications from two distinct MBeans --> 17 <value>bean:name=testBean1</value> 18 <value>bean:name=testBean2</value> 19 </list> 20 </property> 21 <property name="handback"> 22 <bean class="java.lang.String"> 23 <constructor-arg value="This could be anything..."/> 24 </bean> 25 </property> 26 <property name="notificationFilter" ref="customerNotificationListener"/> 27 </bean> 28 </list> 29 </property> 30 </bean> 31 32 <!-- implements both the NotificationListener and NotificationFilter interfaces --> 33 <bean id="customerNotificationListener" class="com.example.ConsoleLoggingNotificationListener"/> 34 35 <bean id="testBean1" class="org.springframework.jmx.JmxTestBean"> 36 <property name="name" value="TEST"/> 37 <property name="age" value="100"/> 38 </bean> 39 40 <bean id="testBean2" class="org.springframework.jmx.JmxTestBean"> 41 <property name="name" value="ANOTHER TEST"/> 42 <property name="age" value="200"/> 43 </bean> 44 45</beans>
(handback 객체가 무엇인지, 그리고 NotificationFilter가 무엇인지에 대한 전체적인 논의는 JMX 명세(1.2)의 'The JMX Notification Model'이라는 제목의 섹션을 참조하십시오.)
Spring은 Notifications를 수신하도록 등록하는 것뿐만 아니라 Notifications를 발행하는 것에 대한 support도 제공합니다.
이 섹션은
MBeanExporter를 통해 MBeans로 노출된 Spring-managed 빈과 실제로만 관련이 있습니다. 기존의 user-defined MBeans는 notification 발행을 위해 표준 JMX APIs를 사용해야 합니다.
Spring의 JMX notification publication support에서 핵심 인터페이스는 NotificationPublisher 인터페이스(org.springframework.jmx.export.notification 패키지에 정의됨)입니다. MBeanExporter 인스턴스를 통해 MBean으로 export될 모든 빈은 관련된 NotificationPublisherAware 인터페이스를 구현하여 NotificationPublisher 인스턴스에 대한 access를 얻을 수 있습니다.
NotificationPublisherAware 인터페이스는 단순한 setter 메서드를 통해 구현 빈에 NotificationPublisher의 인스턴스를 제공하며, 빈은 이를 사용해서 Notifications를 발행할 수 있습니다.
NotificationPublisher
인터페이스의 javadoc에 명시된 바와 같이, NotificationPublisher 메커니즘을 통해 events를 발행하는 managed 빈은 notification 리스너의 상태 관리에 대해 책임을 지지 않습니다. Spring의 JMX support가 모든 JMX 인프라스트럭처 이슈를 처리합니다.
애플리케이션 개발자로서 여러분이 해야 할 일은 NotificationPublisherAware 인터페이스를 구현하고 제공된 NotificationPublisher 인스턴스를 사용하여 events 발행을 시작하는 것뿐입니다. NotificationPublisher는 managed 빈이 MBeanServer에 등록된 후에 설정된다는 점에 유의하십시오.
NotificationPublisher 인스턴스를 사용하는 것은 상당히 간단합니다. JMX Notification 인스턴스(또는 적절한 Notification 서브클래스의 인스턴스)를 생성하고, 발행될 event와 관련된 data로 notification을 채운 다음, NotificationPublisher 인스턴스에서 sendNotification(Notification)을 호출하면서 Notification을 전달하면 됩니다.
다음 예제에서, JmxTestBean의 export된 인스턴스는 add(int, int) 오퍼레이션이 호출될 때마다 NotificationEvent를 발행합니다:
1package org.springframework.jmx; 2 3import org.springframework.jmx.export.notification.NotificationPublisherAware; 4import org.springframework.jmx.export.notification.NotificationPublisher; 5import javax.management.Notification; 6 7public class JmxTestBean implements IJmxTestBean, NotificationPublisherAware { 8 9 private String name; 10 private int age; 11 private boolean isSuperman; 12 private NotificationPublisher publisher; 13 14 // other getters and setters omitted for clarity 15 16 public int add(int x, int y) { 17 int answer = x + y; 18 this.publisher.sendNotification(new Notification("add", this, 0)); 19 return answer; 20 } 21 22 public void dontExposeMe() { 23 throw new RuntimeException(); 24 } 25 26 public void setNotificationPublisher(NotificationPublisher notificationPublisher) { 27 this.publisher = notificationPublisher; 28 } 29 30}
NotificationPublisher 인터페이스와 이를 동작하게 하는 machinery는 Spring의 JMX support에서 가장 좋은 기능 중 하나입니다. 그러나 이는 여러분의 클래스들을 Spring과 JMX 모두에 결합시키는 대가를 수반합니다.
항상 그렇듯이, 여기에서의 조언은 실용적으로 접근하라는 것입니다. NotificationPublisher가 제공하는 기능이 필요하고 Spring과 JMX 모두에 대한 coupling을 수용할 수 있다면, 그렇게 하십시오.
Accessing MBeans through Proxies
Further Resources