zoukankan      html  css  js  c++  java
  • Spring Application Event Example

    Spring Application Event

    项目结构

    spring application event项目结构

    工程下载

    https://github.com/xiaoheike/SpringApplicationEventExample.git

    SportEvent

    package nd.esp.com.event;
    
    import org.springframework.context.ApplicationEvent;
    
    public class SportEvent extends ApplicationEvent {
        private static final long serialVersionUID = 1L;
    
        public SportEvent(Object source) {
            super(source);
        }
    }
    

    SportEvent是所有体育运动的父类,继承Spring ApplicationEvent,必须实现带参数构造函数,如上述代码所示。带参数构造函数传入参数可用于携带其他的信息。具体在NBAEvent中可以看到作用。

    NBAEvent

    package nd.esp.com.event;
    
    public class NBAEvent extends SportEvent {
    
        private static final long serialVersionUID = 1L;
    
        private String text;
    
        public NBAEvent(Object source) {
            super(source);
        }
    
        public NBAEvent(String source, String text) {
            super(source);
            this.text = text;
        }
    
        public String news() {
            return text;
        }
    
        @Override
        public String getSource() {
            return String.class.cast(super.getSource());
        }
    }
    

    NBAEvent主题,用于显示NBA相关信息,上述getSource()方法重写了Spring ApplicationEvent 的父类EventObject,可以用于获得构造函数传入的参数。

    SoccerEvent

    package nd.esp.com.event;
    
    public class SoccerEvent extends SportEvent {
    
        private static final long serialVersionUID = 1L;
    
        private String text;
    
        public SoccerEvent(String source) {
            super(source);
        }
    
        public SoccerEvent(Object source, String text) {
            super(source);
            this.text = text;
        }
    
        public String news() {
            return text;
        }
    
        @Override
        public String getSource() {
            return String.class.cast(super.getSource());
        }
    }
    

    SoccerEvent主题,用于显示足球先关信息,和NBAEvent功能类似。

    SportEventListener

    SportEventListener1

    package nd.esp.com.listener;
    
    import nd.esp.com.event.NBAEvent;
    import nd.esp.com.event.SoccerEvent;
    import nd.esp.com.event.SportEvent;
    
    import org.springframework.context.ApplicationListener;
    
    public class SportEventListener implements ApplicationListener<SportEvent> {
    
        public void onApplicationEvent(SportEvent event) {
            if (event instanceof NBAEvent) {
                System.out.println("SportEventListener1:" + NBAEvent.class.cast(event).getSource());
            }
            if (event instanceof SoccerEvent) {
                SoccerEvent soccerEvent = SoccerEvent.class.cast(event);
                System.out.println("SportEventListener1:" + soccerEvent.getSource() + "   " + soccerEvent.news());
            }
        }
    }
    

    SportEventListener2

    package nd.esp.com.listener;
    
    import nd.esp.com.event.NBAEvent;
    import nd.esp.com.event.SoccerEvent;
    import nd.esp.com.event.SportEvent;
    
    import org.springframework.context.ApplicationListener;
    
    public class SportEventListener2 implements ApplicationListener<SportEvent> {
    
        public void onApplicationEvent(SportEvent event) {
            if (event instanceof NBAEvent) {
                System.out.println("SportEventListener2:" + NBAEvent.class.cast(event).getSource());
            }
            if (event instanceof SoccerEvent) {
                SoccerEvent soccerEvent = SoccerEvent.class.cast(event);
                System.out.println("SportEventListener2:" + soccerEvent.getSource() + "   " + soccerEvent.news());
            }
        }
    }
    

    SportEventListener是观察者,当有新事件到来会被调用。SportEvent的功能在这里得到体现,通过创建父类,可以同时监控一类相似的主题,比如NBA事件以及足球事件。这样可以少些监听者。可以有多个观察者监听相同的时间,这里是指SportEvent。

    SportEventPublisher

    package nd.esp.com.publisher;
    
    import nd.esp.com.event.NBAEvent;
    import nd.esp.com.event.SoccerEvent;
    import nd.esp.com.event.SportEvent;
    
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class SportEventPublisher implements ApplicationContextAware {
        private ApplicationContext applicationEventPulisher = null;
    
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationEventPulisher = applicationContext;
        }
    
        public void publishEvent(SportEvent sportEvent) {
            applicationEventPulisher.publishEvent(sportEvent);
        }
    
        public static void main(String[] args) {
            String[] xmlConfig = new String[] { "applicationContext.xml" };
            // 使用ApplicationContext来初始化系统
            ApplicationContext context = new ClassPathXmlApplicationContext(xmlConfig);
            SportEventPublisher publisher = (SportEventPublisher) context.getBean("applicationContextAware");
            publisher.publishEvent(new NBAEvent("NBA sport:骑士队获得总冠军"));
            publisher.publishEvent(new SoccerEvent("Scorrer sport:标题:中国获得世界杯冠军", "中国击败世界各国,取得10连冠"));
    
        }
    
    }
    

    SportEventPublisher当有新的时间时,由它发布,这个类继承Spring ApplicationContextAware,能够自动注入ApplicationContext对象。这个类实现了主题的通知功能。

    appicationContext.xml(单线程)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        <bean id="applicationContextAware" class="nd.esp.com.publisher.SportEventPublisher"></bean>
    	<bean id="applicationListener1" class="nd.esp.com.listener.SportEventListener1"></bean>
    	<bean id="applicationListener2" class="nd.esp.com.listener.SportEventListener2"></bean>
    </beans>
    

    这两个bean是必须的,id可以任意,spring针对SportEventPublisher肯定是有经过特殊处理的,要不然该类中的ApplicationEventPublisher无法注入对应类。

    这样的配置默认是采用单线程,为了提高效率可以使用多线程。修改application.xml文件如下即可。

    applicationContext.xml(多线程)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    	<bean id="applicationContextAware" class="nd.esp.com.publisher.SportEventPublisher"></bean>
    	<bean id="applicationListener1" class="nd.esp.com.listener.SportEventListener1"></bean>
    	<bean id="applicationListener2" class="nd.esp.com.listener.SportEventListener2"></bean>
    	
    	<bean id="taskExecutor"  
    	    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">  
    	    <property name="corePoolSize" value="5" />  
    	    <property name="keepAliveSeconds" value="30000" />  
    	    <property name="maxPoolSize" value="1000" />  
    	    <property name="queueCapacity" value="200" />  
    	</bean>  
    	<bean id="applicationEventMulticaster"  
    	    class="org.springframework.context.event.SimpleApplicationEventMulticaster">  
    	    <property name="taskExecutor" ref="taskExecutor" />  
    	</bean>
    </beans>
    

    idapplicationEventMulticaster不能够改变,猜测是spring需要根据这个id注入对象。

    SimpleApplicationEventMulticaster

    多线程或者单线程可以通过该类中的方法

    @SuppressWarnings("unchecked")
    public void multicastEvent(final ApplicationEvent event) {
    	for (final ApplicationListener listener : getApplicationListeners(event)) {
    		Executor executor = getTaskExecutor();
    		if (executor != null) {
    			executor.execute(new Runnable() {
    				public void run() {
    					listener.onApplicationEvent(event);
    				}
    			});
    		}
    		else {
    			listener.onApplicationEvent(event);
    		}
    	}
    }
    

    多线程产经下变量executor的值不为空,单线程则相反。

    运行结果##

    spring application event example执行结果

    教程结束,感谢阅读。
    欢迎转载,但请注明本文链接,谢谢。
    2016.5.12 17:49

  • 相关阅读:
    移动运营四:如何优化页面布局
    移动运营三:如何进行场景洞察
    移动运营二:如何更加了解你的用户
    移动运营一:如何进行运营效果分析
    操作系统的系统调用
    从图灵机到操作系统的启动
    伸展树(splay tree)
    AVL树
    二叉搜索树
    表达式树
  • 原文地址:https://www.cnblogs.com/xiaoheike/p/5486333.html
Copyright © 2011-2022 走看看