0. 前言
这篇文章可能不是常规的笔记风格,而更偏向于随记,我会将听课过程中觉得是我不了解的或者是很有意思的点记录下来,启发思维
本文很多地方都指出某一款开源项目体现出了标准化的优点,那么在我的认知中,标准化究竟包括哪些方面?
- 结构标准化:某一个项目或者说某一个插件除实现自身设计目的外,应该确保Java程序设计核心思路:代码体现框架思路,配置文件完成实现,也就是:(1)代码仅完成思路的框架搭建,不涉及硬编码;(2)各类实例化所需信息都由配置文件完成
除标准化外,本文还提出了一个切合框架编程的,体现某开源项目优势的另一角度——简洁化,这里也需要说明我所认为的简洁化包括哪些方面?
- 调用简洁化:某一个项目被调用时,应存在一个高维度的接口,封装了本项目的功能,从而让调用者在完成框架设计时,只需要知道一个通用形的入口,而具体实例化谁则完全由配置文件决定
- 功能简洁化:某一个项目之所以被实现,其目的就是对某一类繁琐的功能需求进行包装和简化,功能简洁化存在于每一个有意义的项目中
1. 反射机制
反射机制我想讲的不多,主要是理清反射的优势所在,我们在写代码的时候,不是非要全都选择反射来实现,只有在所提到的需求产生时,反射才会更加有效:
需求1:当项目需要在不改变外部jar包源码的前提下,调用其中的private方法或是修改private变量
在需求1下,我们可以使用反射机制的setAccessible
方法来将private对象处理为可访问对象
需求2:当项目需要在不指定类名和方法名的前提下,完成程序框架的搭建
需求2也是反射的核心作用——搭建框架
。反射通过名称完成调用,而名称是可以通过String对象赋值和修改的,这就保证了反射机制的灵活性(C++留下了羡慕的泪水),可以说,这个功能是Java最具吸引力的功能之一,它意味着可以用几段简短的的框架代码+配置文件完成一个复杂的项目实现。
2. JDBC
2.1 Connection
Connection接口除了完成连接数据库的工作外,还有一个很有意义的职能:控制事务处理
。Mysql的事务处理分为三类:开启事务、提交事务、回滚事务。对应的Connection中也有相关方法实现:
//开启事务:
setAutoCommit(boolean autoCommit) //将此连接的自动提交模式设置为给定状态。 true为自动提交;false为手动提交
//提交事务:
commit() //使自上次提交/回滚以来所做的所有更改成为永久更改,并释放此Connection对象当前持有的所有数据库锁。
//回滚事务:
rollback() //撤消当前事务中所做的所有更改,并释放此 Connection对象当前持有的所有数据库锁。
之所以专门提出这个职能,是因为它的回滚机制可以保证数据复写的安全性,再结合Java的异常处理,可以保证只有在需求数据均处理成功,才对数据库做永久修改,否则取消修改,回滚,样例代码如下:
try(){
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接对象,设置开启事务
conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
conn.setAutoCommit(false);
//3.定义sql
String sql = "update account set balance = 1500 where id = 3";
//4.获取执行sql对象
stmt = conn.createStatement();
//5.提交事务
conn.commit();
}catch(Exception throwables){
//回滚事务
conn.rollback();
throwables.printStackTrace();
}
2.2 SQL注入与解决
SQL注入
问题是一个很有意思的“攻击手段”,它启示了我们:
如果单纯使用字符串拼接来组建操作者的输入和我们想要设置的句柄,很可能让操作者通过一些
特殊输入
来达到篡改句柄的目的。这不只是数据库存在的问题,也可能出现在任何有特殊String字段的项目里。
此外,PreparedStatement
解决问题的方式也带给我们新的启示,启示1:
想要解决SQL注入这一类字符串拼接问题,重要的就是去识别可能产生影响的
特殊String字段
,并把它们标识为转义字符
,这样就保证了拼接进来的输入的纯粹性,即纯粹是一段String字符串,而不会和我们设置的句柄产生互动
启示2:
PreparedStatement
所提出的预编译思路,是一种通用的性能提升思路,它不仅适用于MySql,也可以用于任何需要提前准备解析与加载资源的情况,预编译意味着只要操作者对资源的需求没有变化,而只是输入参数发生改变,我们就不需要重复进行解析与加载资源的操作
3. Maven
Maven的设计思路是特别有参考意义的,它具有标准化和简洁化两个极具吸引力的特征
标准化:
Maven的标准化体现在标准化项目结构与标准化项目生命周期两个方面,这使得一个Maven项目可以跨IDE运行,这也是Java的核心思想:一套代码,任何情况,任意运行
标准化的项目结构,既包括其设立的标准化文件结构,也包括其对Jar包的导入标准化(标准化的字段:GroupID, ArtifactId, Version
)
简洁化:
Maven的简洁化则体现在两个方面:一是通过仓库的设计,将Jar包的管理简洁化,设计者不需要去考虑Jar包的管理,只需要配置仓库,然后按规定调用;二是通过pom.xml配置文件,将Jar包的导入简洁化,设计者只需要标准化的几个字段,然后刷新配置文件,就可以实现Jar包的自动导入
4. MyBatis
MyBatis的设计思路仍然体现出了标准化和简洁化的思路
标准化:
连接数据库与Sql语句
硬编码
被抽取到配置文件中实现,实际代码只需要定义Mapper
接口,调用方法就可以完成不同的数据库操作(体现对结构的标准化)
简洁化:
1)操作数据库被封装为由设计者自己决定的一个
Mapper
映射接口,通过一行调用代码完成实现,大大简化了JDBC操作流程
2)读取表的一列,将一列值统一赋值给一个自定义的类,这一原本繁琐的返回值工作也由MyBatis自动实现,简化了返回流程
PS:
对于简洁化的第二点,如果自定义类的属性名与MySql里列名不同,MyBatis虽然无法自动实现封装,但可以通过resultMap标签自动配置匹配(非常灵活)
5. Tomcat和Servlet
Tomcat是一个web服务器,针对的痛点问题是:在HTTP协议的请求和回应过程中,关于请求文本的解读以及回应文本的编写是存在很多重复性工作的。所以可以有一个功能包,来帮助我们解决和HTTP请求与回应相关的所有任务。
而Servlet则是一个在Tomcat框架下,进行请求的解读和回应的编写的功能包,针对的痛点问题是:解决前端对动态显示的需求(接收数据-》处理数据-》回应数据-》显示数据)。
在Tomcat和Servlet的设计中,也有很多值得参考的设计思路,我们仍然从标准化和简洁化两个角度来分析
标准化:
1)Tomcat将请求和响应都封装成符合Java语言调用习惯的set和get方法,并集成了对路径的解析工作
2)Servlet将自己的生命周期封装为一个接口的不同方法,Tomcat通过生命周期顺序,调用这些标准化方法,实现了对HTTP请求的处理
简洁化:
1)Tomcat自动进行路径的访问,请求的解析,回应中缺省句式的补足,使用者可以集中于调用set和get方法,而不需要再去考虑字符串拆解与拼接的工作
2)Servlet将自己的生命周期封装为一个接口,然后提供一个实现接口的HTTP类。这样,编程者只需要重写doGet和doPost方法,而Servlet的生命周期控制则由Tomcat调用接口方法实现
6. MVC模式和三层架构
MVC模式是一种后端开发的设计思路,它将后端处理分成了三个层次,所以是一种体现标准化
的模式:
而三层架构是基于MVC的更应用化的扩展,也是平时设计一个访问功能所必须经过的标准化
流程,它可以使得代码开发过程中:(1)职责单一,各司其职;(2)分工协作,开发高效;(3)代码复用,便于分享
7. Cookie和Session
Cookie和Session主要是为了解决以下痛点问题:开发过程中,希望可以识别同一浏览器发起的请求,以便直接读取一些由该用户发起的,希望保留的数据
。
由于HTTP是无状态的,所以我们只能在HTTP传输的信息中新增一门Cookie技术
,Cookie由服务器向浏览器传输并由浏览器存储
,浏览器访问服务器时,会将对应该服务器的Cookie以HTTP请求头发给服务器。
Session基于Cookie开发,由服务器存储。并以Cookie的形式向浏览器发送存储Session的地址(SessionId,浏览器不同,该值就会不同,从而使得各个浏览器拥有不同的会话信息存储空间),这样就保证了一次会话中Session的统一性
。
Cookie和Session的不同如下:
8. Filter
Filter处理的痛点问题是:当服务器每个资源都对某一个前置功能有所依赖时,我们需要在每一个资源里重复调用该前置功能,这就属于冗余编程了
因此,Filter的简洁性
正是体现在它解决的痛点问题中。我们通过设置Filter,可以让浏览器在访问服务器每个资源前,都必须经过Filter预先处理;服务器在返回时,也需要再经过一遍Filter的返回逻辑
其具体的流程如下图所示:
9. Ajax
Ajax全称异步javascript以及异步xml通讯技术。它要解决的痛点问题有两个:
-
JavaScript代码与服务器的双向数据通信,前者是浏览器自有技术,即请求包,而后者之前只能通过JSP实现对response的解读,而无法让JavaScript接收;
-
浏览器在保持原页面的基础上与服务器进行异步数据通信,这个是JSP也无法实现的功能
Ajax解决第一个问题的逻辑可以理解为:创建一个发包和接包的新进程,由JavaScript
处的socket
发送请求信息至新新进程,新进程打包成request
发送至对应URL并接收response
,然后将response
处理后,作为数据传回JavaScript
的socket
,由socket
处理成JavaScript
中的变量resp
该逻辑也侧面证明了其执行的是异步数据通信
Ajax的设计同样体现了标准性
,即让前后端完全分离,同步交互通过浏览器请求实现,异步交互通过Ajax实现。前端也可通过Ajax向浏览器请求后,动态显示相应内容
10. Vue
Vue技术解决的痛点问题是:前端编程中DOM操作(HTML结构操作,即标签内容的增删改)的繁琐流程,必须要在JavaScript中通过getElement获取对象后,再编写对应的操作语句
因此,Vue提出的解决方案是:
- 对标签中需要处理的数据建立模型并绑定在对应标签位置,模型和HTML中的数据是双向互通的,一方的修改会导致另一方的同步变化,由此解决了直接在标签中产生动态数据的需求
- 对标签中需要处理的逻辑建立对应指令(书写在标签中),由此解决了对标签本身进行修改的需求
Vue的实现原理可以简单理解为:Vue通过将自己的指令在后台解析成对应的JavaScript的DOM语句,从而实现了功能。因此Vue可以看做是对JavaScript的封装
Vue的简洁性
设计正是体现在此