Java 监听器

一、监听器简介

监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
监听器可以用来检测网站的在线人数,统计网站的访问量等等!

二、监听器组件

监听器涉及三个组件:事件源,事件对象,事件监听器

当事件源发生某个动作的时候,它会调用事件监听器的方法,并在调用事件监听器方法的时候把事件对象传递进去。

我们在监听器中就可以通过事件对象获取得到事件源,从而对事件源进行操作!

二、模拟监听器

1.监听器

监听器定义为接口,监听的方法需要事件对象传递进来,从而在监听器上通过事件对象获取得到事件源,对事件源进行修改!

/**
 * 事件监听器
 *
 * 监听Person事件源的eat和sleep方法
 */
interface PersonListener{

    void doEat(Event event);
    void doSleep(Event event);
}
2.事件源

事件源是一个Person类,它有eat和sleep()方法。
事件源需要注册监听器(即在事件源上关联监听器对象)
如果触发了eat或sleep()方法的时候,会调用监听器的方法,并将事件对象传递进去

/**
 *
 * 事件源Person
 *
 * 事件源要提供方法注册监听器(即在事件源上关联监听器对象)
 */

class Person {

    //在成员变量定义一个监听器对象
    private PersonListener personListener ;

    //在事件源中定义两个方法
    public void Eat() {

        //当事件源调用了Eat方法时,应该触发监听器的方法,调用监听器的方法并把事件对象传递进去
        personListener.doEat(new Event(this));
    }

    public void sleep() {

        //当事件源调用了Eat方法时,应该触发监听器的方法,调用监听器的方法并把事件对象传递进去
        personListener.doSleep(new Event(this));
    }

    //注册监听器,该类没有监听器对象啊,那么就传递进来吧。
    public void registerLister(PersonListener personListener) {
        this.personListener = personListener;
    }

}
3.事件对象

事件对象封装了事件源。
监听器可以从事件对象上获取得到事件源的对象(信息)

/**
 * 事件对象Even
 *
 * 事件对象封装了事件源
 *
 * 在监听器上能够通过事件对象获取得到事件源
 *
 *
 */
class Event{
    private Person person;

    public Event() {
    }

    public Event(Person person) {
        this.person = person;
    }

    public Person getResource() {
        return person;
    }

}

测试:

public static void main(String[] args) {

    Person person = new Person();

    //注册监听器()
    person.registerLister(new PersonListener() {
        @Override
        public void doEat(Event event) {
            Person person1 = event.getResource();
            System.out.println(person1 + "正在吃饭呢!");
        }

        @Override
        public void doSleep(Event event) {
            Person person1 = event.getResource();
            System.out.println(person1 + "正在睡觉呢!");
        }
    });


    //当调用eat方法时,触发事件,将事件对象传递给监听器,最后监听器获得事件源,对事件源进行操作
    person.Eat();
}
  • 事件源:拥有事件
  • 监听器:监听事件源所拥有的事件(带事件对象参数的)
  • 事件对象:事件对象封装了事件源对象

事件源要与监听器有关系,就得注册监听器【提供方法得到监听器对象】
触发事件源的事件,实际会提交给监听器对象处理,并且把事件对象传递过去给监听器。

三、Servle监听器

在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别ServletContext, HttpSession和ServletRequest这三个域对象

和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由WEB容器负责注册,开发人员只需在web.xml文件中使用<listener>标签配置好监听器。

1.监听对象的创建和销毁

HttpSessionListener、ServletContextListener、ServletRequestListener分别监控着Session、Context、Request对象的创建和销毁

  • HttpSessionListener(可以用来收集在线者信息)
  • ServletContextListener(可以获取web.xml里面的参数配置)
  • ServletRequestListener
public class Listener1 implements ServletContextListener,
        HttpSessionListener, ServletRequestListener {

    // Public constructor is required by servlet spec
    public Listener1() {
    }

    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("容器创建了");
    }

    public void contextDestroyed(ServletContextEvent sce) {

        System.out.println("容器销毁了");
    }


    public void sessionCreated(HttpSessionEvent se) {

        System.out.println("Session创建了");
    }

    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("Session销毁了");
    }


    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {

    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {

    }
}
  • 监听器监听到ServletContext的初始化了,Session的创建和ServletContext的销毁。(服务器停掉,不代表Session就被销毁了。Session的创建是在内存中的,所以没看到Session被销毁了)

四、SpringBoot中监听器的使用例子

private static final Map<String, UserSync> USER_SYNC_MAP = new HashMap<>();

  @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        LOGGER.info("监听到spring启动成功,初始化对接接口中");
        ApplicationContext context = event.getApplicationContext();
        //初始化同步接口
        Map<String, UserSync> userSyncMap = context.getBeansOfType(UserSync.class);
        for (UserSync userSync : userSyncMap.values()) {
            LOGGER.info("初始化《"+userSync.getSyncSystemCode()+"》系统接口成功...");
            USER_SYNC_MAP.put(userSync.getSyncSystemCode().toLowerCase(), userSync);
        }
        LOGGER.info("对接接口初始化完毕");
    }
public interface UserSync {

    /**
     * 是否拥有当前用户
     * @param jobNumber
     * @return
     */
    Boolean haveUser(String jobNumber);

    /**
     * 获取对接的系统ID
     * @return
     */
    String getSyncSystemCode();
}
@Component
public class DcUserSyncImpl implements UserSync {

    public static final Logger LOGGER = LoggerFactory.getLogger(DcUserSyncImpl.class);
    @Autowired
    private PersonRepository personRepository;

    @Override
    public Boolean haveUser(String jobNumber) {
        Person person = personRepository.findFirstByJobNumber(jobNumber);
        if(person==null||person.getOpendc()==null){
            return false;
        }
        return person.getOpendc();
    }

    @Override
    public String getSyncSystemCode() {
        return "dataCenter";
    }

}

推荐阅读更多精彩内容