zoukankan      html  css  js  c++  java
  • Java Spring 自定义事件监听

    ApplicationContext 事件

    定义一个context的起动监听事件

    import org.springframework.context.ApplicationListener;
    import org.springframework.context.event.ContextStartedEvent;
    
    public class EventStart implements ApplicationListener<ContextStartedEvent>{
    
        @Override
        public void onApplicationEvent(ContextStartedEvent arg0) {
            System.out.println("上下文 开始 事件");
        }
    }
    要定义一个事件监听,首先你得有一个事件,ContextStartedEvent 是一个固定的、具体的事件,Java spring自带的,通过实现
    ApplicationListener<ContextStartedEvent >
    就可以监控这个事件了
    ContextStartedEvent 的定义 
    @SuppressWarnings("serial")
    public class ContextStartedEvent extends ApplicationContextEvent {
    
        /**
         * Create a new ContextStartedEvent.
         * @param source the {@code ApplicationContext} that has been started
         * (must not be {@code null})
         */
        public ContextStartedEvent(ApplicationContext source) {
            super(source);
        }
    
    }
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.event.ContextStoppedEvent;
    
    public class EventStop implements ApplicationListener<ContextStoppedEvent> {
    
        @Override
        public void onApplicationEvent(ContextStoppedEvent arg0) {
            System.out.println("上下文 停止 事件");
        }
    }

    主方法

            ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("b.xml");
            context.start();
            
            Dept dept = (Dept)context.getBean("dept");
            dept.getLeader();
            
            context.stop();
            context.registerShutdownHook();

    b.xml

    <bean id="eventStart" class="test4.EventStart"></bean>
    <bean id="eventStop" class="test4.EventStop"></bean>

    输出

    初始化 bean.洪七公
    初始化 bean.null
    家
    我
    上下文 开始 事件
    部门领导洪七公
    上下文 停止 事件
    销毁 bean.null
    销毁 bean.洪七公

    为什么主方法中一调用 start 方法,监听事件就可以自己被调用 呢

    start方法真正执行的是AbstractApplicationContext的start方法,在方法里,除了真正start要处理的内容外,还额外加了事件处理,

    @Override
        public void start() {
            getLifecycleProcessor().start();
            publishEvent(new ContextStartedEvent(this));
        }

    所加的事件就是ContextStartedEvent事件,在将实例了ApplicationListener<ContextStartedEvent>的bean通过xml注册到spring容器中时,容器自动调用了该bean的onApplicationEvent方法

     自定义事件

    public class Person {
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    public class Work extends ApplicationEvent{
        private static final long serialVersionUID = 1L;
        private Person ps;
    
        public void setPs(Person ps) {
            this.ps = ps;
        }
    
        public Work(Object source) {
            super(source);
        }
    
        public void doWorking() {
            String name = this.ps.getName();
            System.out.println(name + " 今天没有完成100张图片制作,并且听到这个任务时,情绪时而激动,时而低落");
        }
    }
    //该类要注册到spring容器,然后容器会自动调用实现ApplicationListener接口的类的onApplicationEvent方法
    public class WorkListener implements ApplicationListener<Work>{
    
        @Override
        public void onApplicationEvent(Work event) {
            // TODO Auto-generated method stub
            System.out.println("摄像头记录到:");
            event.doWorking();
        }
    }
    public class Sleep extends ApplicationEvent{
    
        private Person ps;
        public void setPs(Person ps) {
            this.ps = ps;
        }
    
        private static final long serialVersionUID = 2L;
        public Sleep(Object source) {
            super(source);
        }
        
        public void doSleeping() {
            String name = this.ps.getName();
            System.out.println(name + " 开始休息了");
        }
    }
    //该类要注册到spring容器,然后容器会自动调用实现ApplicationListener接口的类的onApplicationEvent方法
    public class SleepListener implements ApplicationListener<Sleep> {
    
        @Override
        public void onApplicationEvent(Sleep event) {
            System.out.println("摄像头记录到:");
            event.doSleeping();
        }
    }
    public class Report implements ApplicationEventPublisherAware{
        private ApplicationEventPublisher publisher;
        
        @Override
        public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
            this.publisher = applicationEventPublisher;
        }
        
        public void work() {
            System.out.println("开始小明的工作报告");
            Work work = new Work(this);
            ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("d.xml");
            Person xm = (Person)context.getBean("xiaoming");
            work.setPs(xm);
            this.publisher.publishEvent(work);
        }
        
        public void sleep() {
            System.out.println("开始小明的睡眠报告");
            Sleep sl = new Sleep(this);
            ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("d.xml");
            Person xm = (Person)context.getBean("xiaoming");
            sl.setPs(xm);
            this.publisher.publishEvent(sl);
        }
    }
        <bean name="xiaoming" class="test6.Person">
            <property name="name" value="小明"></property>
        </bean>
        
        <bean id="wkReport" class="test6.Report"></bean>
        <bean id="wkMonitor" class="test6.WorkListener"></bean>
        <bean id="slMonitor" class="test6.SleepListener"></bean>
    public class Main {
        public static void main(String[] args) {
            ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("d.xml");
            Report rp = (Report)context.getBean("wkReport");
            rp.work();
            rp.sleep();
            context.close();
        }
    }

    输出

    开始小明的工作报告
    摄像头记录到:
    小明 今天没有完成100张图片制作,并且听到这个任务时,情绪时而激动,时而低落
    开始小明的睡眠报告
    摄像头记录到:
    小明 开始休息了

    事件本身,Work,Sleep不需要注册到sping容器中。

    想要让

    rp.work();rp.sleep();
    工作,睡觉这样的方法/行为,可以被监控,除了这些方法本身要处理的内容外,
    还需要为这个方法定义一个具体的事件类(此例中是Work,Sleep,这些具体的事件类不需要注册到spring容器,因为他们在工作、睡觉这些方法中已经被调用了),
    然后将对应的事件类添加到
    ApplicationEventPublisher事件处理的逻辑中;
    在我们调用 工作、睡觉这些方法时,就会触发事件处理逻辑,
    spring容器会自动检测哪些bean实现了与之相对应的ApplicationListener监听类,然后调用其onApplicationEvent方法

  • 相关阅读:
    链表面试题(一):反转链表的算法实现
    Flutter随笔(二)——使用Flutter Web + Docker + Nginx打造一个简单的Web项目
    Spring MVC知识要点
    ddd
    可编辑下拉框(ie6/chrome)
    Ajax+PHP简单实例
    移动app嵌套h5页面meta标签
    为什么python适合写爬虫?(python到底有啥好的?!)
    自学java第一天(写第一个程序)
    git桌面工具
  • 原文地址:https://www.cnblogs.com/perfei/p/12183405.html
Copyright © 2011-2022 走看看