该系列将以spring boot为研究对象,配合注解的配置方式探究spring的两大核心IoC和AOP。
读者需要对spring boot的使用和配置有一个基本认识。
在正式讲解Spring相关内容前,首先对基于java的web知识点做一个简单的梳理。
Servlet,是为了扩展java作为web服务的一种规范
从源码上来看,Servlet就是一组接口和类的定义,即我们可以认为J2EE中的Servlet的相关代码为我们使用java构建web服务提供了各种api,这其中包括最常用的Request,Response,ServletConfig等一系列类或接口。
除此之外,还有一个非常重要的类——ServletContext.
ServletContext
ServletContext是针对单个Web应用的,存储该应用的全局信息的空间
即ServletContext对于所有的请求是共享的。既然如此,那么ServletContext一定保存了一些全局变量,从源码中可以得知获取这些变量的方法:
package javax.servlet;
public interface ServletContext {
...
String getInitParameter(String var1);
Enumeration<String> getInitParameterNames();
Object getAttribute(String var1);
Enumeration<String> getAttributeNames();
下面我们看看某个应用的ServletContext的具体的内容,输出ServletContext中的attribute如下:
javax.servlet.context.tempdir C:\Users\XXX\...\localhost\ROOT
org.springframework.web.context.WebApplicationContext.ROOT org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@68267da0
总之,ServletContext是每个java web项目都有的一个全局空间。
Filter
过滤器,字面意思,该类针对每次请求进行处理。
public interface Filter {
//初始化
void init(FilterConfig var1) throws ServletException;
//过滤操作
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3);
//结束操作
void destroy();
}
其中FilterConfig类是过滤器的配置类,可以从其获取到该过滤器的变量名和ServletContext等信息。
ServletRequest,ServletResponse
Servlet系列中三个最常见的变体——HttpServlet,ServletRequest,ServletResponse。
其中ServletRequest和ServletResponse是构建起每次web请求的两个基本接口——用于承载前端的请求和后端的反馈。
public interface ServletRequest {
Object getAttribute(String var1);
void setAttribute(String var1, Object var2);
String getCharacterEncoding();
String getContentType();
ServletInputStream getInputStream() throws IOException;
String getParameter(String var1);
关于ServletRequest有两点需要额外注意:
- getParameter()方法获取前端请求的参数
- setAttribute() 和 getAttribute() 方法传递的数据只会存在于Web容器内部
从具体实现来说,对于前端表格发来的请求,后端的request专门有一个Parameters类用于承载所有的请求参数,当然其内部还是一个Map的封装。因此,获取前端请求是通过getParameter()来实现的。
那么getAttribute()方法获取的什么参数呢?
注意还有配套的setAttribute()方法,这两个方法都只能在web容器内部实现。
有点类似于Session,那么和Session的区别是什么呢?
我们知道Session用于保存用户在后台的数据,那么request.getAttribute()方法就是获取本次请求设置的数据。下一次同一用户的请求将可能不携带该数据。
也就是说,session的getAttribute()和setAttribute()对于同一用户的每次请求呈现出数据共享,而request的getAttribute()和setAttribute()对于同一用户的每次请求数据不共享。
ServletResponse的设计思路和ServletRequest相似。
Servlet
最后看看请求的本体——Servlet.
该接口的作用即是处理每一次的请求。
public interface Servlet {
void init(ServletConfig var1);
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2);
String getServletInfo();
void destroy();
}
具体的继承关系如下:
可能很多人对于HttpServlet这个类既熟悉又陌生。
HttpServlet是在没有框架前,处理请求的唯一方法实现。
通过继承HttpServlet并覆盖其doGet或者doPost方法,该类能实现处理前端请求的任务。参考使用HttpServlet处理前端请求
HttpServlet源码概览如下:
public abstract class HttpServlet extends GenericServlet {
protected void doGet(...){...}
protected void doPost(...){...}
protected void doPut(...){...}
protected void doDelete(...){...}
而doGet,doPost,doPut,doDelete的输出实现又是依赖于输出流PrintStream来实现的。
什么是Servlet