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

  • 相关阅读:
    反转链表 16
    CodeForces 701A Cards
    hdu 1087 Super Jumping! Jumping! Jumping!(动态规划)
    hdu 1241 Oil Deposits(水一发,自我的DFS)
    CodeForces 703B(容斥定理)
    poj 1067 取石子游戏(威佐夫博奕(Wythoff Game))
    ACM 马拦过河卒(动态规划)
    hdu 1005 Number Sequence
    51nod 1170 1770 数数字(数学技巧)
    hdu 2160 母猪的故事(睡前随机水一发)(斐波那契数列)
  • 原文地址:https://www.cnblogs.com/xiaoheike/p/5486333.html
Copyright © 2011-2022 走看看