• spring中的事件 applicationevent 讲的确实不错


    event,listener是observer模式一种体现,在spring 3.0.5中,已经可以使用annotation实现event和eventListner里。
    我们以spring-webflow里的hotel booking为例,看一下实现,步骤如下:
    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;
     }
    }
     

    event需要继承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
     }
    }
     

    listener需要实现ApplicationListener。
    注意在spring 3.0.5中的ApplicationListener是带泛型的,这样BookingEventsListener只会监听BookingCreatedEvent事件。
    另外可以用@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 = new BookingCreatedEvent(this, booking);
      //触发event
      this.context.publishEvent(bookingCreatedEvent);
     }
    }
     

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

    @Autowired
    private ApplicationContext applicationContext;
     

    那么event listener这种模式的好处是什么呢?举个例子,如果客人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或者数据库中转。

  • 相关阅读:
    vuex action 与mutations 的区别
    vue element-UI 升级报错Cannot find module "element-ui/lib/theme-default/index.css"
    mac 端口占用问题
    关于npm 淘宝镜像 以及package.json里包的更新
    plugin-barcodescanner 报错
    ios集成极光推送:Undefined symbols for architecture arm64: "_dns_parse_resource_record", referenced from:?
    Undefined symbols for architecture i386: "_deflate", referenced from:
    ionic3 打包Xcode 9 Swift Language Version (SWIFT_VERSION) Ask 报错
    ionic3 调用摄像头 当键盘弹出时候 出现摄像头 背景
    ionic3 更新打开apk android 8.0报错
  • 原文地址:https://www.cnblogs.com/littlemonk/p/5705476.html
Copyright © 2020-2023  润新知