Spring的ApplicationEvent

作者: 守住阳光 | 来源:发表于2018-09-27 13:50 被阅读0次

            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 <BookingCreatedEvent> {

            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

        本文链接:https://www.haomeiwen.com/subject/goqeoftx.html