一、ApplicationListener的原理
ApplicationListener(应用程序监听器)是Spring Framework中的一个事件机制,Spring在运行时触发各类事件,如web应用程序上下文的启动完成事件、servlet请求及响应事件、消息事件等。这些事件可以被应用程序监听器感知到并处理,可以进行自定义的扩展和操作。
二、ApplicationListener的增加和删除
增加ApplicationListener较为简单,只需要实现ApplicationListener接口,并在Spring配置文件中配置即可。
public class MyEventListener implements ApplicationListener{ @Override public void onApplicationEvent(ApplicationEvent event) { //do something } }
在Spring配置文件中添加如下配置:
删除ApplicationListener同样简单,只需要将实现ApplicationListener接口的类从Spring配置文件中删除即可。
三、ApplicationListener的作用
ApplicationListener可以处理各类应用程序事件,如ApplicationContext、ServletRequest、HttpSession等
1、ApplicationContext事件:监听应用程序上下文的启动和关闭事件,并可以对应用程序上下文进行自定义的扩展。
public class MyContextListener implements ApplicationListener{ @Override public void onApplicationEvent(ContextStartedEvent event) { ApplicationContext context = event.getApplicationContext(); //do something with context } }
2、ServletRequest事件:监听servlet请求事件,可以对HttpServletRequest和HttpServletResponse进行自定义的扩展。
public class MyRequestListener implements ApplicationListener{ @Override public void onApplicationEvent(ServletRequestEvent event) { HttpServletRequest request = (HttpServletRequest) event.getServletRequest(); HttpServletResponse response = (HttpServletResponse) event.getServletResponse(); //do something with request and/or response } }
3、HttpSession事件:监听HttpSession的创建、销毁、属性变更等事件。
public class MySessionListener implements ApplicationListener{ @Override public void onApplicationEvent(HttpSessionEvent event) { HttpSession session = event.getSession(); //do something with session } }
四、ApplicationListener的用法
ApplicationListener可用于编写各类系统插件和监听器,可以独立于应用程序自身。
举一个应用场景的例子,一个电商平台在用户下单完成后,需要将订单信息发送给短信平台,以便发送短信给用户,通知订单提交成功。
第一步:定义事件
public class OrderEvent extends ApplicationEvent { private String orderNo; private String mobile; public OrderEvent(Object source, String orderNo, String mobile) { super(source); this.orderNo = orderNo; this.mobile = mobile; } public String getOrderNo() { return orderNo; } public String getMobile() { return mobile; } }
第二步:编写监听器
public class SmsListener implements ApplicationListener{ @Override public void onApplicationEvent(OrderEvent event) { String orderNo = event.getOrderNo(); String mobile = event.getMobile(); //send sms to mobile with orderNo } }
第三步:发布事件
public class OrderService { @Autowired private ApplicationContext ctx; public void submitOrder(String orderNo, String mobile) { //do something OrderEvent event = new OrderEvent(this, orderNo, mobile); ctx.publishEvent(event); } }
在订单提交成功后调用OrderService的submitOrder方法,然后就能发送短信给用户了。
五、ApplicationListener不执行
在某些情况下,需要限制应用程序事件的执行。有两种方法可以做到这一点:
1、在事件监听器中进行判断,当不满足条件时不执行事件
public class MyEventListener implements ApplicationListener{ @Override public void onApplicationEvent(SomeEvent event) { if(/* condition not met */){ return; } //do something } }
2、使用条件注解,只有满足条件时才会启用事件监听器
@Conditional(MyCondition.class) public class MyEventListener implements ApplicationListener{ @Override public void onApplicationEvent(SomeEvent event) { //do something } } public class MyCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //return true or false based on some condition } }
六、ApplicationListener加载两次
在Spring应用程序中,有些情况下,同一个ApplicationListener会被加载多次,导致事件执行多次。针对这种情况,有以下两种解决方案:
1、将ApplicationListener注册为单例模式
2、在Spring配置文件中启用事件多播器,将ApplicationListener注册到多播器中
七、ApplicationListener指定执行顺序
在一个Spring应用程序中,有可能存在多个ApplicationListener对同一事件同时进行监听。当需要保证它们的执行顺序时,可以使用@Order注解来指定它们的执行顺序。
@Order(1) public class MyFirstEventListener implements ApplicationListener{ //do something } @Order(2) public class MySecondEventListener implements ApplicationListener { //do something } @Order(3) public class MyThirdEventListener implements ApplicationListener { //do something }
八、ApplicationListener阻止程序启动
在某些情况下,需要在Spring应用程序启动过程中进行一些自定义的验证和检查,如果不通过则需要阻止程序启动。可以实现ApplicationListener接口的onApplicationEvent方法,并在检查失败时抛出异常,即可阻止程序的启动。
public class MyContextListener implements ApplicationListener{ @Override public void onApplicationEvent(ContextRefreshedEvent event) { //do some checks if(/*check failed*/){ throw new RuntimeException("Failed to start application"); } } }
九、ApplicationListenerDetector
ApplicationListenerDetector用于动态扫描项目中已经实现ApplicationListener接口的类,并将这些类自动注册到Spring的ApplicationContext中成为监听器。
以上是ApplicationListener的详解,可以看到它的使用非常广泛。通过ApplicationListener可以自定义应用程序事件及其相应的处理逻辑,可以使用AOP方式,实现应用程序的各项业务逻辑。使用Spring面向切面编程(AOP),可以为应用程序添加上更多的可重用性、扩展性、松散耦合性。