spring之自定义事件及监听

spring的事件及监听和ApplicationContext

  ApplicationContext中的事件处理都是通过applicationEvent类和ApplicationListener接口来实现的。在spring发展历史上从spring4.2开始一直到spring5和springBoot新增了注解实现。所以现在分为编程式实现和注解实现。

老版本xml配置实现事件及监听的实现

       ①自定义事件(继承ApplicationEvent) 

1 public class MyEvent extends ApplicationEvent {
2         public RainEvent(Object source) {
3             super(source);
4         }
5     }

    ②监听器类RainListener1和RainListener2

       RainListener1 

1 public class RainListener1 implements ApplicationListener<MyEvent>{
2 
3         @Override
4         public void onApplicationEvent(MyEvent event) {
5             System.out.println("唐僧大喊:" + event.getSource() + "赶快收衣服喽!");
6         }
8     }

 RainListener12

1 public class RainListener2 implements ApplicationListener<MyEvent>{
3         public void onApplicationEvent(MyEventevent) {
4             System.out.println("我们:" + event.getSource() + "太好了不用上课了!");
5         }
6     }

③xml配置

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4 xmlns:context="http://www.springframework.org/schema/context"
 5 xsi:schemaLocation="http://www.springframework.org/schema/beans
 6 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7 http://www.springframework.org/schema/context
 8 http://www.springframework.org/schema/context/spring-context-3.2.xsd">
 9 <!-- 把监听器注册到spring容器中 -->
10 <!-- 通过spring容器发布事件后,监听器会调用指定方法进行处理 -->
11 <bean class="com.lut.eventListener.MyListener2"></bean>
12 <bean class="com.lut.eventListener.MyListener1"></bean>
13 </beans>

④main方法实现

1 String path = "com/lut/eventListener/event.xml";2     ApplicationContext container = 
3         new ClassPathXmlApplicationContext(path);
4     container.publishEvent(new RainEvent("下雨了!"));

结果(顺序和xml配置顺序相关。):

我们:下雨了!太好了不用上课了!
唐僧大喊:下雨了!赶快收衣服喽!

springBoot下的实现

  自定义事件

    

 1 package lut.eventlistener;
 2 import org.springframework.context.ApplicationEvent;
 3 public class Myevent extends ApplicationEvent {
 4     String name ;
 5     String age;
 6     public Myevent(Object source,String name,String age) {
 7         super(source);
 8         this.age=age;
 9         this.name=name;
10     }
11     public Myevent(Object source) {
12         super(source);
13     }
14 }

2、监听

   实现1非注解(implements ApplicationListener<Myevent>) 

 1 package lut.eventlistener;
 2 
 3 import org.springframework.context.ApplicationListener;
 4 import org.springframework.scheduling.annotation.Async;
 5 import org.springframework.stereotype.Component;
 6 
 7 @Component
 8 public class ProcessListener implements ApplicationListener<Myevent> {
 9     @Async
10     @Override
11     public void onApplicationEvent(Myevent event) {
12         try {
13             Thread.sleep(2000);
14         } catch (InterruptedException e) {
15             e.printStackTrace();
16         }
17         System.out.println("监听到了:"+event.getSource()+event.name+"--"+event.age);
18     }
19 }

注解方式

 1 package lut.eventlistener;
 2 
 3 import org.springframework.context.event.EventListener;
 4 import org.springframework.stereotype.Component;
 5 
 6 @Component
 7 public class AnnListener {
 8     @EventListener
 9     public void say(Myevent event){
10         System.out.println("注解监听到了:"+event.getSource()+event.name+"--"+event.age);
11     }
12 }

3、controller方法

package lut.eventlistener;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class EventController {

    @Autowired
    private ApplicationContext context;
    @RequestMapping("event")
    public String getEvent(){
         context.publishEvent(new Myevent("相遇了","xiaogang","12"));
        System.out.println("controller执行到return了");
        return "hello";
    }
}

结果:

非注解结果

监听到了:相遇了xiaogang--12
controller执行到return了

----------------------------------------------------------------------

注解结果:2种监听可同时存在注解打印在非注解打印输出之前

注解监听到了:相遇了xiaogang--12(注解式的输出)
监听到了:相遇了xiaogang--12(非注解式的输出)
controller执行到return了

总结:

ApplicationEvent和ApplicationListener抽象类的接口到spring 5 一直未改变。

ApplicationEvent源码:

package org.springframework.context;
import java.util.EventObject;
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @see org.springframework.context.ApplicationListener
 * @see org.springframework.context.event.EventListener
 */
public abstract class ApplicationEvent extends EventObject {
    /** use serialVersionUID from Spring 1.2 for interoperability. */
    private static final long serialVersionUID = 7099057708183571937L;

    /** System time when the event happened. */
    private final long timestamp;
    /**
     * Create a new {@code ApplicationEvent}.
     * @param source the object on which the event initially occurred or with
     * which the event is associated (never {@code null})
     */
    public ApplicationEvent(Object source) {
        super(source);
        this.timestamp = System.currentTimeMillis();
    }

    /**
     * Return the system time in milliseconds when the event occurred.
     */
    public final long getTimestamp() {
        return this.timestamp;
    }

}

ApplicationListener源码:

/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.context;

import java.util.EventListener;

/**
 * Interface to be implemented by application event listeners.
 *
 * <p>Based on the standard {@code java.util.EventListener} interface
 * for the Observer design pattern.
 *
 * <p>As of Spring 3.0, an {@code ApplicationListener} can generically declare
 * the event type that it is interested in. When registered with a Spring
 * {@code ApplicationContext}, events will be filtered accordingly, with the
 * listener getting invoked for matching event objects only.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @param <E> the specific {@code ApplicationEvent} subclass to listen to
 * @see org.springframework.context.ApplicationEvent
 * @see org.springframework.context.event.ApplicationEventMulticaster
 * @see org.springframework.context.event.EventListener
 */
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

    /**
     * Handle an application event.
     * @param event the event to respond to
     */
    void onApplicationEvent(E event);

}
原文地址:https://www.cnblogs.com/swfzzz/p/12035407.html