理解 Spring ApplicationListener

ApplicationContext事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件处理。

 如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发。这种事件机制都必须需要程序显示的触发。

其中spring有一些内置的事件,当完成某种操作时会发出某些事件动作。比如监听ContextRefreshedEvent事件,当所有的bean都初始化完成并被成功装载后会触发该事件,实现ApplicationListener<ContextRefreshedEvent>接口可以收到监听动作,然后可以写自己的逻辑。

同样事件可以自定义、监听也可以自定义,完全根据自己的业务逻辑来处理。

内置事件

 

序号Spring 内置事件 & 描述
1

ContextRefreshedEvent

ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext接口中使用 refresh() 方法来发生。此处的初始化是指:所有的Bean被成功装载,后处理Bean被检测并激活,所有Singleton Bean 被预实例化,ApplicationContext容器已就绪可用

2

ContextStartedEvent

当使用 ConfigurableApplicationContext (ApplicationContext子接口)接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。

3

ContextStoppedEvent

当使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。

4

ContextClosedEvent

当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。

5

RequestHandledEvent

这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件。

业务方监听事件举例

比如要监听ContextRefreshedEvent的时可以实现ApplicationListener接口,并且传入要监听的事件

public class InitTask implements ApplicationListener<ContextRefreshedEvent> {

   @Override
   public void onApplicationEvent(ContextRefreshedEvent arg0) {
      // TODO Auto-generated method stub
      QuartzSetService server = (QuartzSetService)arg0.getApplicationContext().getBean("quartzSetService");
      List<QuartzSetVo> jobList = server.getAllTask();
      TaskControlScheduler taskScheduler = (TaskControlScheduler)arg0.getApplicationContext().getBean("taskControlScheduler");
      taskScheduler.init(jobList);
   }

}
自定义事件

可以自定义事件,然后做完业务处理后手动发出。同上集成某个监听接口,接收到事件后进行业务处理

事件定义:

 

public class EmailEvent extends ApplicationEvent{

   private String address;

   private String text;

   public EmailEvent(Object source, String address, String text){

   super(source);

      this.address = address;

      this.text = text;

   }

   public EmailEvent(Object source) {

     super(source);

   }

   //......address和text的setter、getter

}

监听定义

public class EmailNotifier implements ApplicationListener{

   public void onApplicationEvent(ApplicationEvent event) {

     if (event instanceof EmailEvent) {

        EmailEvent emailEvent = (EmailEvent)event;

        System.out.println("邮件地址:" + emailEvent.getAddress());

        System.our.println("邮件内容:" + emailEvent.getText());

     } else {

        System.our.println("容器本身事件:" + event);

     }

   }

}

业务触发

public class SpringTest {

   public static void main(String args[]){

     ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");

     //创建一个ApplicationEvent对象

     EmailEvent event = new EmailEvent("hello","abc@163.com","This is a test");

     //主动触发该事件

     context.publishEvent(event);

   }

}

不管是内置监听还是外部自定义监听一定要把实现ApplicationListener的类定义成一个bean才行,可以是通过注解@Component等也可以通过xml的方式去执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值