Spring的ApplicationEvent

        event,listener是observer模式一种体现,这里我们介绍ApplicationEvent的使用。

一、如何使用?

1、 建立event

public class BookingCreatedEvent extends ApplicationEvent {

        private static final long serialVersionUID = 3039313222160544111L;

        private Booking booking;

        public BookingCreatedEvent(Object source) {

              super(source);

        }

        public BookingCreatedEvent(Object source, Booking booking) {

              super(source);

              this.booking = booking;

        }

        public Booking getBooking() {

              return booking;

        }

}

        BookingCreatedEvent需要继承ApplicationEvent。

2、建立listener

@Component

public  class  BookingEventsListener  implements  ApplicationListener {

        private static final Logger log = Logger.getLogger();

        //listener实现

        public void onApplicationEvent(BookingCreatedEvent event) {

                  log.debug("bookingId:" + event.getBooking().getId());

                  //do something 

       }

}

        BookingEventsListener 需要实现ApplicationListener 并重写onApplicationEvent方法。ApplicationListener带泛型,如果泛型参数为BookingCreatedEvent,则表示只监听BookingCreatedEvent类型的事件,如果泛型参数为ApplicationEvent ,则表示监听所有类型的事件。另外可以用@Component来注册组件,这样就不需要在spring的配置文件中指定了。

3、触发event

@Service("bookingService")

@Repository

public class JpaBookingService implements BookingService, ApplicationContextAware {

        private ApplicationContext context;

        public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {

              log.debug("Autowired applicationContext");

              this.context = applicationContext;

        }

        //省略的代码

        @Transactional

        public  void  persistBooking(Booking booking)throws HibernateException, SQLException {

               em.persist(booking);

              log.debug("fire BookingCreatedEvent");

              BookingCreatedEvent bookingCreatedEvent =newBookingCreatedEvent(this, booking);

              //触发event

              this.context.publishEvent(bookingCreatedEvent);

        }

}

        触发要实现ApplicationContextAware,用于引入ApplicationContext,由于bookingService也 是spring组件,所以在系统启动的时候,ApplicationContext已经注入。也可以用如下方式直接注入 ApplicationContext。

@AutowiredprivateApplicationContext applicationContext;

二、有什么好处?    

解耦:

        如上例子,如果客人booking了hotel以后,系统要发email给客人,那我们就可以在listener的do something处加上发送email的代码。

        上面我们讲用@Component把listener注册成了spring的组件,这样listener的用途是在runtime的时候解耦。而如果我们把listener用配置文件的方式注册的话,主要用途是在部署的时候解耦。在实际应用中,两种情况都有。

        另外要注意的一点是,service和listener是同步的,在service中的persistBooking有注册 @Transactional的情况下,listener中的do something和service中的persistBooking是在同一个tansaction下。

        如果要做异步,需要通过MQ或者数据库中转。

你可能感兴趣的:(Spring的ApplicationEvent)