Listener(监听器)

原文
https://zhuanlan.zhihu.com/p/65219353

转行开发一年多了,很心疼去年浪费了这么多时间在SSM上。有一段时间,觉得自己好像什么都懂,但又什么都不懂。这种感觉是非常难受的。仿佛浑身充满了力气,却每一拳都打在棉花上。我想更深入地了解Java,写出更好更优雅的代码,结果买了书翻开的那一瞬间就发现不是自己想要的,书中所讲并没有直指我心里的疑问。

我的疑问是什么呢?作为非科班,自知起步比别人已经晚了一大截。虽然希望最好能搞懂整个框架,却也知道欲速则不达。然而,哪怕窥得其中一二想必也会很满足。我以为这件事很简单,但却浪费了我大半年时间。

去年年底一次偶然的机会,促使我开始了复习JavaWeb基础的漫漫长路。从此一发不可收拾,从动态代理、注解、ThreadLocal以及JDBC,一路过关斩将,收获颇丰。才发现,原来学习框架时感到无力,是特么基础不牢靠...真的是基础不牢,地动山摇,这话一点没错。

如果当初学习JavaWeb时,我对反射、动态代理、注解、泛型、JDBC等知识点有现在这程度,学会使用SSM估计就是一星期的事情...基础实在太重要了(话虽这么说,JavaWeb对于零基础来说难度是客观存在的)。

真的恨不得坐时光机回到去年抽自己一巴掌:滚回去好好学JavaWeb!望大家引以为戒!

Cookie和Session 写得不错
https://zhuanlan.zhihu.com/p/42918845
会话机制的目的是什么:标识用户,跟踪状态。

2个感知监听
|—HttpSessionBindingListener
|—HttpSessionActivationListener
感知监听都是Session相关的,我已经在Cookie与Session讲过,这里就不提了。
6个常规监听器
|—ServletContext
|—ServletContextListener(生命周期监听)
|—ServletContextAttributeListener(属性监听)
|—HttpSession
|—HttpSessionListener(生命周期监听)
|—HttpSessionAttributeListener(属性监听)
|—ServletRequest
|—ServletRequestListener(生命周期监听)
|—ServletRequestAttributeListener(属性监听)

6个常规监听器,分成三对,每对分属一类,每对分别对应JavaWeb三大域对象(除去JSP的Page域):ServletContext、HttpSession、ServletRequest。也就是说/换句话说/同义句替换,1个生命周期监听和1个属性监听成一对,每个域对象有一对监听。
生命周期监听:每当Tomcat创建或销毁三大域对象,都会被这些监听器察觉,然后它们会做相应的操作(调用自身的特定方法)。也就是说,见名知义,它监听三大域对象的创建和销毁。
属性监听:每当我们给域对象设置值或者从里面取值,都会被它们监听到,然后还是触发它们特定的方法。也就是说,见名知义,监听三大域对象get/setAttribute()。

Q1.那么,何时创建或销毁三大域对象?也就是,何时三大生命周期监听器触发?
Q2.那么,何时会给域对象设置值或者从里面取值?也就是,何时三大属性监听器触发?
Q3.访问一个Servlet,HttpSessionListener一定会触发吗?(换个角度就是,等价于,同义句替换,访问Servlet,Session一定会创建吗?)

A1:
在项目启动时ServletContextListener监听到ServletContext对象创建
每一次请求Tomcat都会创建一个Request,它的创建会被ServletRequestListener监听到
如果Servlet中调用了request.getSession(),则Tomcat会创建Session(如果根据JSESSIONID找不到对应的),这会被HttpSessionListener监听到
请求结束,Request销毁,被监听到
用户30分钟未访问,Session过期销毁,被监听到
项目关停,ServletContext销毁,被监听到
A2:
你在代码里敲setAttribute(“XX”,“YY”)、getAttribute(“XX”)的时候。
A3:
只有当在Servlet中调用request.getSession(),且根据JSESSIONID找不到对应的Session时,才会创建新的Session对象,这时,触发被监听。
第二次请求,浏览器会带上JSESSIONID,此时虽然还是request.getSession(),但是会返回上次那个。
根据JSESSIONID去找Session这个过程是隐式的,我们看到的就是getSession()。

那么,为啥监听器能起作用。监听器的底层原理其实涉及到一种设计模式:观察者模式(Observer)
先来看监听器的定义:
监听器就是一个实现了特定接口的普通Java程序,这个程序专门用于监听另一个Java对象的方法调用或者属性改变。当被监听对象发生上述事件后,监听器某个方法将立即被执行。
但是,还是没讲到点子上(原理)。为啥监听器能监听?在原作者看来,一个方法能执行,必然是被调用!有两种可能:
可能1.定时任务
可能2.对象调用/静态方法调用
监听器肯定不是通过定时任务实现的,毕竟它的方法调用时机是在“被监听对象特定行为发生时”。既然不是定时任务,那么肯定是被监听对象主动告诉监听器的!
是不是觉得很荒唐?被监听对象主动告诉监听对象,那还叫监听器?监听个鬼哦…
但是大家有没有想过,监听器英文名叫Listener,我翻译成“倾听者”有何不可?就是说,Listener对象一直在侧耳倾听,等待被监听对象发号施令。这个翻译骚不骚?
也就是说:被监听对象发生某个行为时,会主动告诉Listener(对象方法调用),让它执行对应的特定操作!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值