Spring中ApplicationContext对事件的支持 Spring 中事件的传递

 

Spring中ApplicationContext对事件的支持 Spring 中事件的传递  

2008-09-22 13:34:30|  分类: 技术 |  标签: |字号 订阅

ApplicationContext具有发布事件的能力。这是因为该接口继承了ApplicationEventPublisher接口。Spring中与事件有关的接口和类主要包括ApplicationEvent、ApplicationListener。
定义一个事件的类需要继承ApplicationEvent或者ApplicationContextEvent抽象类,该抽象类中只有一个构造函数,并且带有一个Object类型的参数作为事件源,并且该事件源不能为null,因此我们需要在自己的构造函数中执行super(Object)。
public class UserEvent extends ApplicationEvent
{
   private String eventContent;
   public String getEventContent(){
      return eventContent;
   }
   public void setEventContent(String eventContent){
      this.eventContent = eventContent;
   }
   public UserEvent(Object source,String eventContent){
      super(source);
      this.eventContent = eventContent;
   }
}
针对一种事件,可能需要特定的监听器,因此,监听器需要实现ApplicationListener接口。当监听器接收到一个事件的时候,就会执行它的onApplicationEvent()方法。由于Spring IoC中的事件模型是一种简单的、粗粒度的监听模型,当有一个事件到达时,所有的监听器都会接收到,并且作出响应,如果希望只针对某些类型进行监听,需要在代码中进行控制。
public class UserListener implements ApplicationListener
{
   public void onApplicationEvent(ApplicationEvent event){
      if(event instanceof UserEvent){ //只对UserEvent类型进行处理
         UserEvent ue = (UserEvent)event;
         String result = ue.getEventContent();
         System.out.println("Event Content:"+result);
      }
   }
}
对于发布事件,我们可以实现ApplicationContextAware或者ApplicationEventPublisherAware接口。
public class UserBiz implements ApplicationContextAware
{
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
    this.applicationContext = applicationContext;
}
public void service(String thing)
{
    UserEvent event = new UserEvent(this,thing);
    event.setEventContent("I shoud "+thing);
    applicationContext.publishEvent(event);
}  
}
或者如下:
public class UserBiz2 implements ApplicationEventPublisherAware
{
private ApplicationEventPublisher applicationEventPublisher;
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher)
{
this.applicationEventPublisher = applicationEventPublisher;
}
public void service(String thing)
{
    UserEvent event = new UserEvent(this,thing);
    event.setEventContent("I shoud "+thing);
    applicationEventPublisher.publishEvent(event);
}
}
至此便完成了事件的发布,当ApplicationContext接收到事件后,事件的广播是Spring内部给我们做的,不需要了解具体的细节。其实在Spring读取配置文件之后,利用反射,将所有实现ApplicationListener的Bean找出来,注册为容器的事件监听器。当接收到事件的时候,Spring会逐个调用事件监听器。剩下要做的就是在配置文件中配置监听器。
<bean class="footprint.spring.ioc.event.UserListener"/>
Spring容器自身会发布一些事件,包括ContextClosedEvent、ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent。

 

 

 

 

Spring 中事件的传递

LockedIPEvent.java

java 代码
  1. package com.gjx.spring.event;   
  2.   
  3. import org.springframework.context.ApplicationEvent;   
  4.   
  5. public class LockedIPEvent extends ApplicationEvent {   
  6.   
  7.     public LockedIPEvent(Object source) {   
  8.         super(source);   
  9.     }   
  10.   
  11. }   

LockedIPListener.java

java 代码
  1. package com.gjx.spring.event;   
  2.   
  3. import org.apache.commons.logging.Log;   
  4. import org.apache.commons.logging.LogFactory;   
  5. import org.springframework.context.ApplicationEvent;   
  6. import org.springframework.context.ApplicationListener;   
  7.   
  8. public class LockedIPListener implements ApplicationListener {   
  9.     //在这里,监听器应该只作一个记录功能   
  10.     private Log logger=LogFactory.getLog(LockedIPListener.class);   
  11.     public void onApplicationEvent(ApplicationEvent event) {   
  12.         if (event instanceof LockedIPEvent) {   
  13.             logger.info("Locked IP  ["+event.getSource()+"] try to login !");   
  14.         }   
  15.     }   
  16.   
  17. }   

UserManager.java

java 代码
  1. package com.gjx.spring.event;   
  2.   
  3. import java.util.List;   
  4.   
  5. import org.springframework.beans.BeansException;   
  6. import org.springframework.context.ApplicationContext;   
  7. import org.springframework.context.ApplicationContextAware;   
  8.   
  9. /*实现啦这个接口就会通过ApplicationContext来取得 这是一个接口的注入  
  10.  * 如果使用这样的事件就会和Spring 偶合在一起啦  
  11.  *   
  12.  */  
  13. public class UserManager implements ApplicationContextAware {   
  14.     private List lockedIPList;   
  15.   
  16.     private ApplicationContext context;   
  17.     public List getLockedIPList() {   
  18.         return lockedIPList;   
  19.     }   
  20.   
  21.     public void setLockedIPList(List lockedIPList) {   
  22.         this.lockedIPList = lockedIPList;   
  23.     }   
  24.     public boolean isLogin(String username,String password,String ip){   
  25.         if(lockedIPList.contains(ip)){   
  26.             context.publishEvent(new LockedIPEvent(ip)); //发布这个事件   
  27.             return true;   
  28.         }   
  29.         return false;   
  30.     }   
  31.   
  32.     public void setApplicationContext(ApplicationContext context) throws BeansException {   
  33.         this.context=context;   
  34.            
  35.     }   
  36. }   

beans.xml

xml 代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">  
  3.   
  4. <beans>  
  5.        
  6.     <!-- 监听器类的ID设不设置都无所谓 ,如果不想要日志信息,直接删掉下面这句就OK啦。所以很方便-->  
  7.     <bean class="com.gjx.spring.event.LockedIPListener"/>  
  8.        
  9.     <bean id="userManager" class="com.gjx.spring.event.UserManager">  
  10.         <property name="lockedIPList">  
  11.             <list>  
  12.                 <value>222.111.111.4</value>  
  13.                 <value>222.111.111.7</value>  
  14.                 <value>222.111.111.9</value>  
  15.             </list>  
  16.         </property>  
  17.     </bean>  
  18. </beans>  

JUnit的测试代码

TestSpring.java

java 代码
  1. package Test.com.gjx.spring;   
  2.   
  3. import java.io.BufferedOutputStream;   
  4. import java.io.IOException;   
  5. import java.io.InputStream;   
  6. import java.util.Date;   
  7. import java.util.Locale;   
  8.   
  9. import junit.framework.TestCase;   
  10.   
  11. import org.springframework.context.ApplicationContext;   
  12. import org.springframework.context.support.ClassPathXmlApplicationContext;   
  13. import org.springframework.context.support.GenericApplicationContext;   
  14. import org.springframework.core.io.Resource;   
  15.   
  16. import com.gjx.spring.HelloAction;   
  17. import com.gjx.spring.event.UserManager;   
  18.   
  19. public class TestSpring extends TestCase {     
  20.   
  21.     public void testEvent() {   
  22.         ApplicationContext context = new ClassPathXmlApplicationContext(   
  23.                 "beans.xml");   
  24.         UserManager userManager = (UserManager) context.getBean("userManager");   
  25.         userManager.isLogin("冬国""1234567""222.111.111.4");   
  26.     }   
  27. }   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值