前言:
B站学习之后笔记:
GenericServlet
-
我们编写一个Servlet类直接实现Servlet接口有什么缺点?
-
我们一般只需要实现service方法,可是其他方法也要全部重写,代码不简化。
-
-
(适配器设计模式Adapter)编写一个GenericServlet类,这个类是一个抽象类,其中只有一个抽象方法service方法。
-
GenericServlet实现Servlet接口。
-
GenericServlet是一个适配器。
-
以后编写所有的Servlet类继承GenericServlet,重写service方法即可。
-
-
思考:GenericServlet是否需要改造一下?更利于我们的编写?
-
提供一个GenericServlet之后,init方法还会执行么?
-
会执行,会执行GenericServlet中的init方法(子类默认执行父类)。
-
-
init方法是谁调用的?
-
Tomcat服务器调用的。
-
-
init方法中ServletConfig对象是谁创建的?是谁传过来的?
-
Tomcat服务器。
-
-
Tomcat服务器如何进行操作的?(以UserServlet对象为例子,自己创建的class)
-
创建UserServlet对象(通过反射机制,调用无参构造方法来去实例化UserServlet对象)。
-
创建ServletConfig对象,Tomcat服务器负责将ServletConfig对象实例化出来。
-
调用Servlet的init方法,service方法......
-
-
ServletConfig
-
什么是ServletConfig?
-
Servlet对象的配置信息对象。
-
ServletConfig对象中封装了<servlet></servlet>标签中的配置信息。(web.xml文件中servlet的配置信息)
-
-
一个Servlet对象对应一个ServletConfig对象。
-
Servlet对象是由Tomcat服务器创建的,ServletConfig对象也是由Tomcat服务器创建的。并且默认情况下,他们都是在用户发送第一次请求时创建的。
-
Tomcat服务器调用Servlet对象的init方法的时候,要传一个ServletConfig对象的参数给init方法。
-
SerlvetConfig接口的实现是Tomcat服务器给实现的。
-
ServletConfig有哪些方法?
-
public String getInitParameter(String name); //通过初始化参数的name获取value public Enumeration<String> getInitParamterNames(); //获取所有的初始化参数的name public ServletContext getServletContext(); //获取ServletContext对象 public String getServletName(); //获取Servlet的name
-
以上的方法在Servlet类当中,都可以通过this调用。因为GenericServlet实现了ServletConfig接口。
-
ServletContext
-
只要在同一个webapp当中,只要在同一个应用当中,所有的Servlet对象就是共享同一个ServletContext对象的。
-
ServletContext对象在服务器启动阶段创建,在服务器关闭的时候销毁。这就是ServletContext对象的生命周期。ServletContext对象是应用级对象。
-
Tomcat服务器中有一个webapps,这个webapps下可以存放webapp,可以存放多个webapp,假设有100个webapp,就有100个ServletContext对象。总之,一个应用,一个webapp肯定只有一个ServletContext对象。
-
ServletContext被称为Servlet上下文对象。(Servlet对象的四周环境对象)。
-
一个ServletContext对象通常对应是一个web.xml文件。
-
ServletContext是一个接口,Tomcat服务器对ServletContext接口进行了实现。
-
ServletContext对象的创建也是Tomcat服务器来完成的。启动webapp的时候创建的。
-
-
ServletContext对象还有另一个名字:应用域(后面还有其他的域:会话域、请求域)
-
如果所有用户共享一份数据,并且这个数据很少的被修改,并且这个数据量很少,可以将这些数据放到ServletContext这个应用域中。
-
为什么是所有用户共享的数据?不是共享的没有意义,因为ServletContext这个对象只有一个,只有共享数据才有意义。
-
为什么数据量要小?因为数据量比较大的话,太占用堆内存,并且这个对象的生命周期比较长,服务器关闭的时候,这个对象才会被销毁。大数据会影响服务器的性能。占用内存较小的数据量可以考虑放进去。
-
为什么这些共享数据很少被修改,或者几乎不修改?所有用户都是共享数据的,如果设计到修改操作的话,必然会存在线程并发所带来的安全问题。所以放在ServletContext对象中的数据一般都是只读的。
-
-
数据量小,所有用户共享,又不修改,这样的额数据放在ServletContext这个应用域当中,会大大提升效率。因为应用域相当于一个缓存,放到缓存中的数据,下次在用的时候,不需要从数据库中再次获取,从而大大提升执行效率。
-
存,删,取:
//存(怎么向ServletContext应用域中存数据) public void setAttribute(String name, Object value); //取(怎么从ServletContext应用域取数据) public Object getAttribute(String name); //删(怎么删除ServletContext应用域的数据) public void removeAttribute(String name);
-
-
注意:以后编写代码不会继承GenericServlet类的,因为我们是B/S结构的系统,这种系统是基于HTTP超文本传输协议的。在Servlet规范中,提供了一个叫HttpServlet,它是专门为Http协议准备的一个Servlet类,我们编写的Servlet类要继承HttpServlet,处理Http协议更方便。
Servlet(接口) 【爸爸】 GenericServlet implements Servlet (抽象类) 【儿子】 HttpServlet extends GenericServlet(抽象类) 【孙子】 以后编写的Servlet都继承HttpServlet类。
-
目前为止接触到了哪些缓存机制?
-
堆内存当中的字符串常量池。
-
“abc”先在字符串常量池中寻找,如果有,直接拿来用。如果没有则新建,然后放进字符串常量池。
-
-
堆内存当中的整数型常量池。
-
[-128 ~ 127]一共256个Integer类型的引用,放在整数型常量池中。没有超出这个范围的话,直接从中取数。
-
-
连接池(Connection Cache)
-
这里所说的连接池中的连接是java语言直接连接数据库的连接对象:java.sql.Connection对象。
-
JVM是一个进程。MySQl数据库是一个进程。进程和进程之间建立连接,打开通道是很费劲的。是很耗费资源的。怎么办?
可以提前先创建好N个Connection连接对象,将连接对象放到一个集合当中,我们把这个放有Connection对象的集合称为连接池。每一次用户连接的时候不需要再新建连接对象,省去了新建的环节,直接从连接池中获取连接对象,大大提升访问效率。
-
连接池
-
最小连接数
-
最大连接数
-
连接池可以提高用户访问效率,当然也可以保证数据库的安全性。
-
-
-
线程池
-
Tomcat服务器本身是支持多线程的。
-
Tomcat服务器是在用户发送一次请求,就新建一个Thread线程对象么?
-
当然不是,实际上Tomcat服务器启动的时候,会先创建N个线程Thread对象,然后将线程对象放到集合当中,称为线程池,用户发送请求之后,需要有一个对应的线程来处理这个请求,这个时候线程对象会直接从线程池中拿,效率比较高。
-
所有WEB服务器,或者应用级服务器,都是支持多线程的,都有线程池机制。
-
-
-
redis
-
NoSQL数据库。非关系型数据库。缓存数据库。
-
-
向ServletContext应用域中存储数据,也等于是将数据存放到缓存Cache中。
-