l. Event Handling - kimxavi/spring_tutorial GitHub Wiki

ApplicationContext는 확실한 타입의 이벤트를 bean이 로딩될 때 만들어낸다. 예를 들어, ContextStartedEvent는 context가 시작될 때 발생하고, ContextStoppedEvent는 context가 중지됐을 때 발생한다. ApplicationContext에서 Event handling 은 ApplicationEvent 클래스와 ApplicationListener 인터페이스에 의해 제공된다. 만약 ApplicationListener를 통해서 bean이 구현되면, ApplicationContext 에게 발생되는 ApplicationEvent를 얻을 때마다 bean에게 통지된다.

Spring Built-in Events

  • ContextRefreshedEvent : ApplicationContext가 초기화되거나 리프레쉬될 때 발생한다. ConfigurableApplicationContext 인터페이스의 refresh() 메소드를 사용해서 발생하기도 한다.
  • ContextStartedEvent : ConfigurableApplicationContext의 start() 메소드를 사용해서 ApplicationContext가 시작할 때 발생한다. 이벤트를 받으면 데이터베이스가 poll 할 수 있거나 정지해있던 어플리케이션이 시작/재시작 할 수 있다.
  • ContextStoppedEvent : ConfigurableApplicationContext의 stop() 메소드를 사용해서 ApplicationContext가 중지될 때 발생한다. 이 이벤트를 수신 한 후 필요한 housekeep 작업을 수행 할 수 있습니다.
  • ContextClosedEvent : ConfigurableApplicationContext의 close() 메소드를 사용해서 ApplicationContext가 닫힐 때 발생한다. context가 닫히는 건 수명이 다했다는 것이다. 이 것은 이제 재시작이나 리프레쉬를 할 수가 없다.
  • RequestHandledEvent : HTTP 요청을 받은 모든 bean에 전달하는 웹 명시적인 이벤트이다.

스프링의 이벤트 처리는 싱글스레드 이다. 그래서 만약 이벤트가 발생하면, 모든 reciver가 메시지를 받아도 프로세스는 블록 되고 흐름은 멈춘다. 그런 이유로, 만약 이벤트 처리를 쓰려면 어플리케이션을 잘 디자인해서 관리해야 한다.

Listening to Context Events

context 이벤트를 listen 하기 위해서, bean은 ApplicationListener 인터페이스를 상속받는다. 인터페이스는 onApplicationEvent() 메소드 하나만을 가지고 있다. HelloWorld.java

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }

   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

CStartEventHandler.java

package com.tutorialspoint;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;

public class CStartEventHandler 
   implements ApplicationListener<ContextStartedEvent>{

   public void onApplicationEvent(ContextStartedEvent event) {
      System.out.println("ContextStartedEvent Received");
   }
}

CStopEventHandler.java

package com.tutorialspoint;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;

public class CStopEventHandler 
   implements ApplicationListener<ContextStoppedEvent>{

   public void onApplicationEvent(ContextStoppedEvent event) {
      System.out.println("ContextStoppedEvent Received");
   }
}

MainApp.java

package com.tutorialspoint;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ConfigurableApplicationContext context = 
      new ClassPathXmlApplicationContext("Beans.xml");

      // Let us raise a start event.
      context.start();
	  
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");

      obj.getMessage();

      // Let us raise a stop event.
      context.stop();
   }
}

Beans.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-3.0.xsd">

   <bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
      <property name="message" value="Hello World!"/>
   </bean>

   <bean id="cStartEventHandler" 
         class="com.tutorialspoint.CStartEventHandler"/>

   <bean id="cStopEventHandler" 
         class="com.tutorialspoint.CStopEventHandler"/>

</beans>

PRINT

ContextStartedEvent Received
Your Message : Hello World!
ContextStoppedEvent Received

Custom Events

커스텀 이벤트를 발생시키기 위한 단계이다.

  1. 이벤트 클래스를 만든다. 그 다음 ApplicationEvent를 상속받은 CustomEvent를 만든다. 이 클래스는 반드시 ApplicationEvent로 부터 상속받은 기본 생성자를 정의해야한다.
  2. 이벤트 클래스를 정의할 때, 다른 클래스로부터 이 것을 발생시킬 수 있다. ApplicationEventPublisherAware 를 상속받아 EventClassPublisher를 발생시켜보자. ApplicationEventPublisherAware를 상속 받았기 때문에 이벤트 발생자로써 컨테이너가 bean에 알리기 위해서 XML 설정 파일에 선언할 필요가 있다.
  3. ApplicationListener를 상속받은 EventClassHandler에 알림으로써 커스텀 이벤트를 처리하는 onApplicationEvent 메소드에서 발생된 이벤트를 처리한다.

CustomEvent.java

package com.tutorialspoint;

import org.springframework.context.ApplicationEvent;

public class CustomEvent extends ApplicationEvent{
   
   public CustomEvent(Object source) {
      super(source);
   }

   public String toString(){
      return "My Custom Event";
   }
}

CustomEventPublisher.java

package com.tutorialspoint;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;

public class CustomEventPublisher 
   implements ApplicationEventPublisherAware {
   
   private ApplicationEventPublisher publisher;

   public void setApplicationEventPublisher
              (ApplicationEventPublisher publisher){
      this.publisher = publisher;
   }

   public void publish() {
      CustomEvent ce = new CustomEvent(this);
      publisher.publishEvent(ce);
   }
}

CustomEventHandler.java

package com.tutorialspoint;

import org.springframework.context.ApplicationListener;

public class CustomEventHandler 
   implements ApplicationListener<CustomEvent>{

   public void onApplicationEvent(CustomEvent event) {
      System.out.println(event.toString());
   }

}

MainApp.java

package com.tutorialspoint;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ConfigurableApplicationContext context = 
      new ClassPathXmlApplicationContext("Beans.xml");
	  
      CustomEventPublisher cvp = 
      (CustomEventPublisher) context.getBean("customEventPublisher");
      cvp.publish();  
      cvp.publish();
   }
}

Beans.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-3.0.xsd">

   <bean id="customEventHandler" 
      class="com.tutorialspoint.CustomEventHandler"/>

   <bean id="customEventPublisher" 
      class="com.tutorialspoint.CustomEventPublisher"/>

</beans>

PRINT

y Custom Event
y Custom Event
⚠️ **GitHub.com Fallback** ⚠️