特别需要注意的知识点
:
多线程
数据库
(SQL
优化
,
索引
,
引擎
,
事务
)
数据结构
1 spring ioc
、
aop
的原理
Spring IOC
依赖注入其实就是控制反转,用
spring
时用
xml
配置的方式的话,都是将
bean
配置在
spring
中,也有
bean
的
property
属性。
spring
容器在初始化时就通过反射将容器中的
bean
实例化,假如
bean
配置中有
property
属性,就会反射
property
属性注入到
bean
中。这就是依赖注入。它分为构造方法注入,
set
方法注入,接口注入,我们最常用的就是
set
方法注入
spring AOP
:
AOP
就是面向切面编程。它主要运用了动态代理中的
Proxy
类和
InvicationHandler
接口实现。举例简单来说假如想要在原来的目标类的前后要加入日志的功能,目标类一定要实现一个接口,如果没有实现接口,
spring
就会用
cglib
包实现
AOP
。推荐的还是要实现一个接口。实现过程大概就是实现了一个
InvicationHandler
接口的方法,里边有一个属性是目标类,在
invoke
方法中利用反射执行目标类的方法,并在其前后加入日志的方法。然后将目标类的类加载器,目标类实现的接口和实现了
InvicationHandler
接口的方法传入到
Proxy
的
newProxyInstance
方法中。这样就实现了
AOP
。这样的话我们就可以在不修改任何代码的情况下在任何目标类中都可以动态的加入记日志的功能。
2 hibernate
延迟加载原理
lazy="true",
则代表对对象实施延迟加载,即,使用
load
函数返回由
CGLIB
或者
javaassist
产生的代理对象,
a.
当不需要取得对象(非主键属性)时,不真正载入内存,从而节约内存空间,并且可以减少对数据的访问频率,高效的返回查询的对象;
b.
当需要取得对象
(
非主键属性
)
时,
hibernate
会先从
session
缓存寻找,再从二级缓存寻找,都找不到,才会使用
select
语句访问数据库。
3
事务隔离级别
什么情况下用低的或者用高的
(
事务
(Transaction)
是访问并可能更新数据库中各种数据项的一个程序执行单元
(unit))
事务隔离级别指的是事务与事务之间的隔离程度
,
事务隔离程度越高,并发性越差、性能越低;事务隔离程度越低,并发性越强、性能越高。
4
事务传播方式哪几种
新建事务
required
–
如无事务就新建事务
required
_new
如有事务挂起当前事务再新建
非事务方式运行
Supports
支持当前事务,如果当前没有事务,就以非事务方式执行。
not_supported -
挂起当前
never
嵌套事务:
Nested
如果当前事务存在,则以嵌套事务的方式执行。否则就按照它自己的事务方式执行。
抛异常
mandatory
支持当前事务,如果当前没有事务,就抛出异常
never
非事务方式执行,如果当前存在事务,则抛出异常。
5 ajax
跨域如何实现
ajax
跨域调用有两种方式,一种是
iframe
的方式,通过设置
document.domain
来实现,一种则是通过设置
jsonp
来实现
7
乐观锁与悲观锁,举例场景
1
、悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,加锁机制,也无法保证外部系统不会修改数据即使在本系统中实现了)。
2
、乐观锁(
Optimistic Locking
)
相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。
8 cookie
与
session
区别和联系,
http
协议是无状态的,怎么区分不同登录用户
Cookie
与
session
的区别
:
1
、
session
保存在服务器,客户端不知道其中的信息;
cookie
保存在客户端,服务器能够知道其中的信息。
2
、
session
中保存的是对象,
cookie
中保存的是字符串。
3
、
session
不能区分路径,同一个用户在访问一个网站期间,所有的
session
在任何一个地方都可以访问到。而
cookie
中如果设置了路径参数,那么同一个网站中不同路径下的
cookie
互相是访问不到的。
区分不同登录用户
:
session
就是一种保存上下文信息的机制,它是针对每一个用户的,变量的值保存在服务器端,通过
SessionID
来区分不同的客户
.
9
阐述
opensessionview
一下,
用和不用
数据库连接、
transaction session
之间
开启和关闭顺序
1.
说说值对象与引用对象的区别?
值对象描述了一种不可变的对象,这些对象完全由其所含的数据值在定义,并不介意副本的存在。
引用对象描述了一种可以被共享(复用)的对象,这些对象的类往往在设计之初就考虑到共享的可能性或者打算用于共享。每个对象对应一个抽象化的实体,这个实体会被多次引用,并且希望这些引用对应一个相同的实例,通过任何一个引用都可以使用或改变这个对象的状态。可以使用相等操作符(
==
)检查两个对象是否相等
2.
谈谈你对反射机制的理解及其用途?
Java
反射机制主要提供了以下功能:在运行时构造一个类的对象;判断一个类所具有的成员变量和方法;调用一个对象的方法;生成动态代理。
主要用途是:通过传递一个字符串值
去调用某一个类的方法。例如根据
spec0
去调用
SpecValue
下的
setSpce0
()方法。
3.ArrayList
、
Vector
、
LinkedList
的区别及其优缺点?
HashMap
、
HashTable
的区别及其优缺点?
-
ArrayList,LinkedList是不同步的,而Vestor是同步的。所以如果不要求线程安全的话,可以使用ArrayList或LinkedList,可以节省为同步而耗费的开销。但在多线程的情况下,有时候就不得不使用Vector了。
-
ArrayList和Vector都是使用Object的数组形式来存储的。Vector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%,
-
ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
-
对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
-
对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。\
hashMap,hashTable
的区别
:
HashTable
中的方法是同步的
HashMap
的方法在缺省情况下是非同步的
因此在多线程环境下需要做额外的同步机制
HashTable
不允许有
null
值
key
和
value
都不允许,而
HashMap
允许有
null
值
key
和
value
都允许
因此
HashMap
使用
containKey
()来判断是否存在某个键
HashTable
使用
Enumeration
,而
HashMap
使用
iterator
Hashtable
是
Dictionary
的子类,
HashMap
是
Map
接口的一个实现类
3.
列出线程的实现方式?如何实现同步?
线程的实现方式有两种:实现
Runnable
接口或者继承
Thread
类
实现同步的方法也有两种:一种是用同步方法,一种是用同步块
wait()
与
notify()
同步方法就是在方法返回类型后面加上
synchronized
同步块就是直接写
synchronized
(这里写需要同步的对象)
{}
4.
如何实现线程安全、高可用的
hashMap
方法一
:
通过
Collections.synchronizedMap()
返回一个新的
Map,
这个新的
map
就是线程安全的
.
是一种悲观锁
.
在进入之前需要获得锁
,
确保独享当前对象
,
然后做相应的修改
/
读取
.
这个要求大家习惯基于接口编程
,
因为返回的并不是
HashMap,
而是一个
Map
的实现
.
方法二
:
重新改写了
HashMap,
使用的是乐观锁
,
只有在需要修改对象时
,
比较和之前的值是否被人修改了
,
如果被其他线程修改了
,
那么就会返回失败
.
5.
条件查询慢如何优化
索引
分区(垂直
水平)
缓存
表优化
SQL
优化
6.String
的
indexof
的实现
先把
String
转换为
char[]
,然后首先找到
target
的的第一个字符开始匹配
.
7.
重写
equal
的同时为什么必须重写
hashcode
?
hashCode
是编译器为不同对象产生的不同整数,根据
equal
方法的定义:如果两个对象是相等(
equal
)的,那么两个对象调用
hashCode
必须产生相同的整数结果,即:
equal
为
true
,
hashCode
必须为
true
,
equal
为
false
,
hashCode
也必须为
false
,所以必须重写
hashCode
来保证与
equal
同步。
8.
判断两个对象是否相等
(1)
判断两个对象的
hashCode
是否相等
如果不相等,认为两个对象也不相等,完毕
如果相等,转入
2
(2)
判断两个对象用
equals
运算是否相等
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等
9.
为什么要重载
equal
方法?
因为
Object
的
equal
方法默认是两个对象的引用的比较,意思就是指向同一内存
,
地址则相等,否则不相等;如果你现在需要利用对象里面的值来判断是否相等,则重载
equal
方法
10.
为什么重载
hashCode
方法?
答案:一般的地方不需要重载
hashCode
,只有当类需要放在
HashTable
、
HashMap
、
HashSet
等等
hash
结构的集合时才会重载
hashCode
,就
HashMap
来说,好比
HashMap
就是一个大内存块,里面有很多小内存块,小内存块里面是一系列的对象,可以利用
hashCode
来查找小内存块
hashCode%size(
小内存块数量
)
,所以当
equal
相等时,
hashCode
必须相等,而且如果是
object
对象,必须重载
hashCode
和
equal
方法。
11.
为什么
equals()
相等,
hashCode
就一定要相等,而
hashCode
相等,却不要求
equals
相等
?
(1)
因为是按照
hashCode
来访问小内存块,所以
hashCode
必须相等。
(2)HashMap
获取一个对象是比较
key
的
hashCode
相等和
equal
为
true
。
之所以
hashCode
相等,却可以
equal
不等,就比如
ObjectA
和
ObjectB
他们都有属性
name
,那么
hashCode
都以
name
计算,所以
hashCode
一样,但是两个对象属于不同类型,所以
equal
为
false
。
12
、
为什么需要
hashCode?
(1)
通过
hashCode
可以很快的查到小内存块。
(2)
通过
hashCode
比较比
equal
方法快,当
get
时先比较
hashCode
,如果
hashCode
不同,直接返回
false
。
13. sleep
和
wait
有什么区别
sleep
是
Thread
类的静态方法。
sleep
的作用是让线程休眠制定的时间,在时间到达时恢复,也就是说
sleep
将在接到时间到达事件事恢复线程执行,
wait
是
Object
的方法,也就是说可以对任意一个对象调用
wait
方法,调用
wait
方法将会将调用者的线程挂起,直到其他线程调用同一个对象的
notify
方法才会重新激活调用者
14. InputStream
和
Reader
的区别
InputStream
和
Reader
都是
java.io
下的抽象类
. InputStream
是表示字节输入流的所有类的超类
. Reader
是用于读取字符流的抽象类
. InputStream
提供的是字节流的读取,而非文本读取,这是和
Reader
类的根本区别。用
Reader
读取出来的是
char
数组或者
String
,使用
InputStream
读取出来的是
byte
数组
.
15. UNICODE,GBK,UTF-8
区别
unicode
,
gbk
和大五码就是编码的值,而
utf-8,uft-16
之类就是这个值的表现形式.而前面那三种编码是一兼容的,同一个汉字,那三个码值是完全不一样的.如"汉"的
uncode
值与
gbk
就是不一样的,假设
uncode
为
a040
,
gbk
为
b030
,而
uft-8
码,就是把那个值表现的形式.
utf-8
码完全只针对
uncode
来组织的,如果GBK要转UTF-8必须先转
uncode
码,再转
utf-8
就OK了.
16.
字节流与字符流的区别
在
java.io
包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。在字节流中输出数据主要是使用
OutputStream
完成,输入使的是
InputStream
,在字符流中输出主要是使用
Writer
类完成,输入流主要使用
Reader
类完成。
字符流处理的单元为
2
个字节的
Unicode
字符,分别操作字符、字符数组或字符串,而字节流处理单元为
1
个字节,操作字节和字节数组。所以字符流是由
Java
虚拟机将字节转化为
2
个字节的
Unicode
字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点
17.
对
excel
操作的两种方法
一种是使用
jxl.jar,
另一种是使用
poi.jar
两者的区别
:
Poi
主要是提供一组操作
windows
文档的
Java API.
JavaExcel
俗称
jxl
是一开放源码项目,通过它
Java
开发人员可以读取
Excel
文件的内容、创建新的
Excel
文件、更新已经存在的
Excel
文件。
jxl
优点:
Jxl
对中文支持非常好,操作简单,方法看名知意。
Jxl
是纯
javaAPI
,在跨平台上表现的非常完美,代码可以再
windows
或者
Linux
上运行而无需重新编写
生成
Excel 2000
标准格式
支持字体、数字、日期操作
能够修饰单元格属性
支持图像和图表
,
但是这套
API
对图形和图表的支持很有限,而且仅仅识别
PNG
格式。
缺点:效率低,图片支持不完善,对格式的支持不如
POI
强大
POI
优点:
效率高
支持公式,宏,一些企业应用上会非常实用
能够修饰单元格属性
支持字体、数字、日期操作
缺点:不成熟
,
代码不能跨平台,貌似不少同行在使用工程中还碰到让人郁闷的
BUG
- iint 与Integer 的区别
int
是基本数据类型
,Integer
是包装类
.
这里还涉及装箱和拆箱问题
,
装箱是指把基本数据类型用它们相应的引用类型包装起来
,
使具有对象的性质
.
拆箱是将引用类型的对象简化成值类型的数据
.
Integer
有两中实例化方法
,
第一种是
new Integer(10),
这个是不提倡的
,
第二种是
Integer.valueOf(),
这种是比较提倡的
,
也是默认的
.valueof
对
-128-127
之间的值有缓存
,
如果
int
值的范围
-128-127,
在
valueof(int)
时
,
它会直接返回
IntegerCache
的缓存给你
.
Integer a=10,Integer b=10
会被翻译成
-> Integer a =Integer.valueOf(100);
所以
a
和
b
得到都是一个
Cache
对象,并且是同一个!而
c
和
d
是新创建的两个不同的对象,所以
c
自然不等于
d
。
- 抽象类和接口有什么区别?
- Abstract class 在java中表示的是一种继承关系,一个类只能使用一次继承,但是一个类可以实现多个interface..
- 在abstract class 可以有自己的数据,也可以有非abstract 的成员方法,而interface中,只能够有静态的不能被修改的数据成员.
- Abstract class 表示的是”is-a”关系,interface 表示的是”like-a”关系
- 抽象类中的变量默认是friendly 型,其值可以在子类中重新定义,也可以重新赋值.
- override与overload 的区别
override (
重写
)
- 方法名,参数,返回值相同
- 子类方法不能缩小父类方法的访问权限
- 子类方法不能抛出比父类方法更多的异常
- 存在父类和子类之间,
- 方法被定义为final不能被重写
特点
:
- 覆盖的方法标志必须要和被覆盖的方法标志完全相同,才能达到覆盖的效果
- 覆盖的方法的返回值必须和被覆盖的方法返回一直
- 所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者其子类
- 被覆盖的方法不能为private.
Overload
- 参数类型,个数,顺序至少有一个不同
- 不能重载只有返回值不同的方法名
- 存在父类和子类,同类中.
特点
:
(1)
在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是
fun(int, float)
,
但是不能为
fun(int, int)
);
(2)
不能通过访问权限、返回类型、抛出的异常进行重载;
(3)
方法的异常类型和数目不会对重载造成影响;
Overriding
和
overload
是
java
多态性的不同表现
.
- 拦截器与过滤器的区别
拦截器
:是在
service
或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串,也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
过滤器:是在
java web
中,你传入的
request,response
提前过滤掉一些信息,或者提前设置一些参数,然后再传入
servlet
或者
struts
的
action
进行业务逻辑,比如过滤掉非法
url,
或者在传入
servlet
或者
struts
的
action
前统一设置字符集,或者去除掉一些非法字符
.
区别
:
(1)
拦截器是基于
java
的反射机制的,而过滤器是基于函数回调
(2)
过滤器依赖与
servlet
容器,而拦截器不依赖与
servlet
容器
(3)
拦截器只能对
action
请求起作用,而过滤器则可以对几乎所有的请求起作用
(4)
拦截器可以访问
action
上下文、值栈里的对象,而过滤器不能
(5)
在
action
的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
Final,finally
和
finalize
的区别
Final
用于声明属性
,
方法和类
,
分别表示属性不可变
,
方法不可覆盖
,
类不可继承
.
Finally
是异常处理语句结构的一部分
,
表示总是执行
Finalize
是
Object
类的一个方法
,
在垃圾收集器执行的时候回调用被回收对象的此方法
,
可以覆盖方法提供垃圾收集时的其他资源回收
,
例如关闭文件
.
5.java
的反射机制
开发性和原因连接是反射系统的两大基本要素
6.
在
java
中如何实现多线程
继承
Thread
类
,
覆盖方法
run(),
我们在创建的
Thread
类的子类中重写
run(),
加入线程所要执行的代码
.
实现
Runnable
接口
,Runnable
接口只有一个方法
run(),
我们声明一个类实现
Runnable
接口并提供这一方法
,
将我们的线程嗲吗写入其中
,
就完成了这一部分的任务
,
但是
Runnable
接口并没有任何对线程的支持
,
我们还必须创建
Thread
类的实例
,
这一点通过
Thread
类的构造函数来实现
.
Redis的基本数据类型:
String。set。list。hash。sorted set(受特的)
Hibernate/mybatis
-
什么是MyBatis?
MyBatis
是一个可以自定义
SQL
、存储过程和高级映射的持久层框架。
MyBatis
消除了几乎所有的
JDBC
代码和参数的手工设置以及对结果集的检索。
MyBatis
可以使用简单的
XML
或注解用于配置和原始映射,将接口和
Java
的
POJO
(
Plain Old Java Objects
,普通的
Java
对象)映射成数据库中的记录。
二
.mybatis
与
ibatis
的区别
1
、
Mybatis
实现了接口绑定,使用更加方便。
在
ibatis2.x
中我们需要在
DAO
的实现类中指定具体对应哪个
xml
映射文件,
而
Mybatis
实现了
DAO
接口与
xml
映射文件的绑定,自动为我们生成接口的具体实现,使用起来变得更加省事和方便。
这可以说是
Mybatis
最重要的改进。
2
、对象关系映射的改进,效率更高
3
、
MyBatis
采用功能强大的基于
OGNL
的表达式来消除其他元素。
MyBatis
采用
OGNL
表达式简化了配置文件的复杂性,使用起来更简洁。
Mybatis
与
hibernate
的区别
相同点
:Hibernate
和
Mybatis
都是
orm
对象关系映射框架,都是用于将数据持久化的框架技术。
Hiberante
与
mybatis
都对
jdbc
进行了封装
,
但是
hibernate
较深度的封装了
jdbc
,对开发者写
sql
的能力要求的不是那么的高,我们只要通过
hql
语句操作对象即可完成对数据持久化的操作了。
Mybatis
封装的没有
hibernate
那么深,我们可以再配置文件中写
sql
语句,可以根据需求定制
sql
语句,数据优化起来较
hibernate
容易很多。
hibernate
可移植性好,需要修改数据库的时候
,
使用
hibernate
只需改变一下数据库方言即可搞定。用
hibernate
框架,数据库的移植变的非常方便。
e
它也提供了一些优化策略,比如说懒加载、缓存、策略模式等都是针对于它的优化方案。
Mybatis
要求程序员写
sql
的能力要相对使用
hibernate
的开发人员要高的多,且可移植性也不是很好。
涉及到大数据的系统使用
Mybatis
比较好,因为优化较方便。涉及的数据量不是很大且对优化没有那么高,可以使用
hibernate
Mybatis
侧重于
sql
映射
,
二
hibernate
侧重于
orm
三.基本
API
1
.
SessionFactory
2
.
Session(save,update,saveOrUpdate,delete,load,get)
3
.
Query
4
.
Transaction
四.
hibernate.cfg.xml
配置文件的加载
使用
XML
文件进行配置时,可以在配置文件中找到对象类映射文件位置,
XML
配置文件的位置默认在
Classpath
下,使用下面的方式来读入
XML
文件以配置
Hibernate
:
Configuration config = new Configuration().configure();
默认的
XML
配置文件名称是
hibernate.cfg.xml
,您也可以自行指定名称,例如:
Configuration config = new Configuration().configure("db.cfg.xml");
五.
SessionFactory
的创建
Configuration
的实例管理
Hibernate
的配置信息,通常用于建立
SessionFactory
,
例如:
SessionFactory sessionFactory = config.buildSessionFactory(); SessionFactory
一旦建立,就被赋予
Configuration
的配置信息,之后改变
Configuration
不会影响已建立的
SessionFactory
实例,如果对
Configuration
改变,则要建立一个新的
SessionFactory
实例,新的实例中才会包括新的配置信息。
六.主键生成方式
1. increment:
由
Hibernate
自动以递增的方式生成标识符
,
每次递增
1
2. identity:
由底层数据库生成标识符
.
前提是底层数据库支持自动增长字段类型
3. sequence: Hibernate
根据底层数据库的序列生成标识符
.
前提是底
层数据库支持序列
4. hilo:
适用于代理主键
, Hibernate
根据
hi/low
算法生成标识符
. Hibernate
把特定的字段
作为
"high".
5. native:
适用于代理主键
,
根据底层数据库对自动生成标识符的支持能力
,
来选择
identity, sequence,
或
hilo
6. uuid.hex:
适用于代理主键
, Hibernate
采用
128
位的
UUID(Universal Identification)
算
法生成标识符
.
7. assigned:
适用于自然主键
,
由
Java
应用程序生成标识符
.
为了能让
Java
应用程序设
置
OID,
不要把方法声明为
private
类型
.
应当尽量避免使用自然主键
.
七.
get()
、
load()
的区别
(1) get()
执行时会立即发送
sql
语句,查询结果,查询后
session
关闭没有影响,
load()
执行时不会立即发送
sql
语句,在使用返回结果的时候才查询,如果
session
关闭,就会出
现惰性加载异常;
(2)get()
查询时
,
如果所传的
id
没有对应的记录,直接返回
null
,不会报错,而
load()
查询时,若果没有对应的
id
会出现
org..hibernate.ObjectNotFoundException
3
)
load()
可返回实体的代理类实例,
get()
直接返回实体
4
)
load()
可在一、二级缓存查找数据,
get()
只在一级缓存找,若无则直接调
用
SQL
语句在数据库中找
八.关于
query
查询
Query.list()
若果没有记录也不是
null
,而是空集合
get(0)
的时候会出现越界异常。
Query.uniqueResult()
有一条记录的时候用此方法。
九.事务
Hibernate
事务默认不自动提交,这种不自动提交是在获得
session
的时候设置的。
而
session.beginTransaction()
是对
session
中事务的设置做检查。
十.类到表的映射的两种方法
1.
在配置文件中配置
hbm2ddl.auto
属性,其值有以下四种:
create
,
validate
,
update
,
create-drop
,然后在编写加载配置文件的类
注意
:
create
:
每次加载
hibernate
时都会删除上一次的生成的表,然后根据你的
model
类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
create-drop
:
每次加载
hibernate
时根据
model
类生成表,但是
sessionFactory
一关闭
,
表就自动删除。
update
:
最常用的属性,第一次加载
hibernate
时根据
model
类会自动建立起表的结构(前提是先建立好数据库),以后加载
hibernate
时根据
model
类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等
应用第一次运行起来后才会。
validate
:
每次加载
hibernate
时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
2.
用类来完成
Configration config = new Configration
()
.configue(); SchemaExport export = new SchemaExport(config); Export.create(true,true);
十一.实体对象的生命周期
1. transient
(临时状态)实体对象在内存中存在,与数据库中的记录无关,不受
session
管理,对对象的修改不会影响数据库。
2. persisent
(持久状态)与表记录相关联,受
session
管理,对对象的修改,在事务提
交或
session
关闭前会执行
update
操作。
3. detached
(游离状态)有表记录关联,不受
session
管理。
各个状态间的转换:
十二.缓存
(1) Session
缓存,实例状态及生命周期由
session
缓存生命周期决定,
Session
生命周期
存在,持久化对象缓存在
session
中,
session
消亡,缓存的持久化对象也就消亡。
(2)
不同的
session
,缓存存储的对象也不同。
(3) Session
缓存持久化实例对象,不持久化实例的某些属性
(4)
一级
session
缓存可以将查询到的持久化实体对象缓存到
session
中,而普通的查询
实体的某属性时,不会在
session
中缓存。
下面方法将实体对象放入
Session
缓存中:
load() get() save() iterate()
在
session
范围缓存的对象,当
session
执行
clear()
或
evict(Object o)
方法后,缓存就会清除所有或某个持久化对象,这样
session
缓存就被清理。
session.flush(); session.clear();
(5)
二级缓存:进程缓存,一个数据库对应一个
SessionFactory
。二级缓存由
SessionFactory
来理。
二级缓存可以通过配置
SessionFactory
来配置打开与关闭。
<property name="cache.use_second_level_cache">false</property>
二级缓存需要第三方插件来设置
十三
hibernate
的优缺点
优点:
1
、程序更加面向对象;
2
、提高了生产率;
3
、方便移植(修改配置文件);
4
、无侵入性。
缺点:
1
、效率比
JDBC
略差;
2
、不适合批量操作。
3
、只能配置一种关联关系
十四
. hibernate
的工作原理
1.
配置好
hibernate
的配置文件和与类对应的配置文件后,启动服务器
2.
服务器通过实例化
Configuration
对象,读取
hibernate.cfg.xml
文件的配置内容,并根据相关的需求建好表或者和表建立好映射关系
3.
通过实例化的
Configuration
对象就可以建立
sessionFactory
实例,进一步,通过
sessionFactory
实例可以创建
session
对象
4.
得到
session
之后,便可以对数据库进行增删改查操作了,除了比较复杂的全文搜索外,简单的操作都可以通过
hibernate
封装好的
session
内置方法来实现
5.
此外,还可以通过事物管理,表的关联来实现较为复杂的数据库设计
十五
.Hibernate
的二级缓存策略
1)
条件查询的时候,总是发出一条
select * from table_name where
…
.
(选择所有字段)这样的
SQL
语句查询数据库,一次获得所有的数据对象。
2)
把获得的所有数据对象根据
ID
放入到第二级缓存中。
3)
当
Hibernate
根据
ID
访问数据对象的时候,首先从
Session
一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照
ID
放入到缓存。
4)
删除、更新、增加数据的时候,同时更新缓存。
缓存的范围
:
1).
事务范围:缓存只能被当前事务访问;缓存的生命周期依赖于事务的生命周期;
缓存的介质是内存。
2).
进程范围:缓存被进程内的所以事务共享;缓存的生命周期依赖于进程的生命
周期;缓存的介质是内存或者硬盘。
3).
集群范围:在集群环境中缓存被一个计算机或者多个计算机共享。
事务范围的缓存是持久化层的第一级缓存,通常是必须的;进程范围或集群范围的缓存是持久化层的第二级缓存,通常可选。进程范围或集群范围的缓存会出现并发问题,可采用
4
中并发访问策略,每种策略对应一种事务级别:
1.
事务型:仅在受管理环境中适用。提供“可重复读”事务隔离级别。(高)
2.
读写型:仅在非集群的环境中适用。提供“已提交读”事务隔离级别。
3.
非严格读写型:不保证缓存与数据库中数据的一致性。极少改,允许偶尔脏读
4.
只读型:从不修改的数据。(最低)
隔离级别越高,并发性能就越低
十六
. Hibernate
的初始化
.
1)
创建
Configeration
类的实例。
它的构造方法:将配置信息
(Hibernate config.xml)
读入到内存。
一个
Configeration
实例代表
Hibernate
所有
Java
类到
Sql
数据库映射的集合。
2)
创建
SessionFactory
实例
把
Configeration
对象中的所有配置信息拷贝到
SessionFactory
的缓存中。
SessionFactory
的实例代表一个数据库存储员源,创建后不再与
Configeration
对象关联。
3)
调用
SessionFactory
创建
Session
的方法
十七
.
状态转换
临时状态
(transient)
1
】不处于
Session
缓存中
2
】数据库中没有对象记录
Java
如何进入临时状态
1
】通过
new
语句刚创建一个对象时
2
】当调用
Session
的
delete()
方法,从
Session
缓存中删除一个对象时。
持久化状态
(persisted)
1
】处于
Session
缓存中
2
】持久化对象数据库中有对象记录
3
】
Session
在特定时刻会保持二者同步
Java
如何进入持久化状态
1
】
Session
的
save()
把临时-》持久化状态
2
】
Session
的
load(),get()
方法返回的对象
3
】
Session
的
find()
返回的
list
集合中存放的对象
4
】
Session
的
update(),saveOrupdate()
使游离-》持久化
游离状态
(detached)
1
】不再位于
Session
缓存中
2
】游离对象由持久化状态转变而来,数据库中可能还有对应记录。
Java
如何进入持久化状态-》游离状态
1
】
Session
的
close()
方法
2
】
Session
的
evict()
方法,从缓存中删除一个对象。提高性能。少用。
十八
. Hibernate
设置事务隔离级别
1.
读操作未提交
(Read Uncommited)
:允许脏读取,不允许更新丢失,该
隔离级别可以通过“排他写锁”实现;
1
2.
读操作已提交
(Read Commited)
:允许不可重复读取,不允许脏读取
2
3.
可重复读
(Repeatable Read)
:禁止不可重复读和脏读取,但有时可能出
现幻像数据;
4
4.
可串行化
(Serializable)
:提供严格的事务隔离。
8
在
hibernate.cfg.xml
中配置隔离级别:
<session-factory> <propertyname=”hibernate.connection_isolation”>4</property> </session-factory>
十九
.
乐观锁,悲观锁
在
org.hibernate
包下有一个名为
LockMode
的类:
包含了主要锁定模式:
1). LockMode.None
2). LockMode.Read
3). LockMode.UPGRADE:
当数据库支持悲观锁,就执行
select
…
for update,
反之普通
select
4). LockMode.UPGRADE_NOWAIT
:对
oracle
执行
select for update nowait
语句
5).LockMode.WRITE
:当
Hibernate
向数据库保存或者更新一个对象时,会自动使用
此模式。
6).LockMode.FORCE
:对于使用了
version
的记录会强制增加
version
的值
悲观锁:
Hibernate
中主要通过显式地设定锁定模式来设置悲观锁定。
有以下几种方式:
1).
调用
Session.load()
指定锁定模式;
2).
调用
Session.lock()
可以为对象设定锁定模式;
3).
调用
Query.setLockMode()
可以设定查询语句获取对象的锁定。
乐观锁:
主要由
Hibernate
提供的版本控制功能来实现乐观锁定。
<version>:
利用一个递增的整数来根据数据库表中记录的版本。
<timestamp>:
用时间戳来跟踪数据库表中记录的版本
二十
.N+1
查询问题
当你查询时首先
hibernate
会发出一天查询所有主键的
sql
语句,然后跟新缓存。
N
就是指首先
hiberante
会到缓存中查询,如果缓存中不存在与之匹配的数据,再会发出
sql
查询。
主要的原因是:默认情况下
iterate
利用缓存数据来查询,当缓存为空会多查询一次,把
ID
加进来。
解决方案
:
Hibernate:
-
设置fetch=FetchType.LAZY,这种方法在合适的时候(具体使用到对象时)还是会发出select语句。
-
用session.createCriteria()做查询
-
使用join fetch做外连接查询。
Mybatis:
-
使用一条SQL语句,主外键相关表的信息全部查询处理
-
使用MyBatis的延迟加载机制. MyBatis的延迟加载机制需要使用cglib包,因此应向工程中添加此包,在配置文件中配置: <settingname="lazyLoadingEnabled"value="true"/>
<settingname="aggressiveLazyLoading"value="false"/>
二十一
.mybatis
中
SQL
映射
SQL
映射实现
1
、在包
com/xunpoit/pojo
下创建
User
类,包含相关属性定义
2
、新建
SQL
映射文件
com/xunpoit/pojo/User.xml
,文件中包含
SQL
代码和映射定义信息,与
User
类同包
<mapper namespace="com.xunpoit.pojo">
<select id="selectUser" parameterType="int“ resultType="com.xunpoit.pojo.User"> select * from t_user where id = #{id} </select>
<select id="selectAllUser" resultType="com.xunpoit.pojo.User"> select * from t_user </select>
<insert id="addUser" parameterType="com.xunpoit.pojo.User"> insert into t_user(id,username,password,addr) values(#{id},#{userName},#{password},#{addr}) </insert> </mapper>
3. SQL
映射
XML
文件仅仅只有一些初级的元素:
cache
–
配置给定模式的缓存
cache-ref
–
从别的模式中引用一个缓存
resultMap
–
这是最复杂而却强大的一个元素了,它描述如何从结果集中加载对象
sql
–
一个可以被其他语句复用的
SQL
块
insert
–
映射
INSERT
语句
update
–
映射
UPDATE
语句
delete
–
映射
DELEETE
语句
select
–
映射
SELECT
语句
二十二
.mybatis
中
#
与
$
的区别
1. #
将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
2. $
将传入的数据直接显示生成在
sql
中。
3. #
方式能够很大程度防止
sql
注入。
$
方式无法防止
Sql
注入。
4.$
方式一般用于传入数据库对象,例如传入表名
.
5.
一般能用
#
的就别用
$.
6.MyBatis
排序时使用
order by
动态参数时需要注意,用
$
而不是
#
一
. Spring
特点
◆方便解耦,简化开发
通过
Spring
提供的
IoC
容器,我们可以将对象之间的依赖关系交由
Spring
进行控制,避免硬编码所造成的过度程序耦合。有了
Spring
,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
◆
AOP
编程的支持
通过
Spring
提供的
AOP
功能,方便进行面向切面的编程,许多不容易用传统
OOP
实现的功能可以通过
AOP
轻松应付。
◆声明式事务的支持
在
Spring
中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
◆方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,在
Spring
里,测试不再是昂贵的操作,而是随手可做的事情。
◆方便集成各种优秀框架
Spring
不排斥各种优秀的开源框架,相反,
Spring
可以降低各种框架的使用难度,
Spring
提供了对各种优秀框架(如
Struts,Hibernate
、
Hessian
、
Quartz
)等的直接支持。
◆降低
Java EE API
的使用难度
Spring
对很多难用的
Java EE API
(如
JDBC
,
JavaMail
,远程调用等)提供了一个薄薄的封装层,通过
Spring
的简易封装,这些
Java EE API
的使用难度大为降低。
二
.spring
框架
组成
Spring
框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
1
、核心容器
(Core)
:核心容器提供
Spring
框架的基本功能
(Spring Core)
。核心容器的主要组件是
BeanFactory
,它是工厂模式的实现。
BeanFactory
使用控制反转(
IOC
)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
2
、
Spring
上下文:
Spring
上下文是一个配置文件,向
Spring
框架提供上下文信息。
Spring
上下文包括企业服务,例如
JNDI
、
EJB
、电子邮件、国际化、校验和调度功能。
3
、
Spring AOP
:通过配置管理特性,
Spring AOP
模块直接将面向切面的编程功能集成到了
Spring
框架中。所以,可以很容易地使
Spring
框架管理的任何对象支持
AOP
。
Spring AOP
模块为基于
Spring
的应用程序中的对象提供了事务管理服务。通过使用
Spring AOP
,不用依赖
EJB
组件,就可以将声明性事务管理集成到应用程序中。
4
、
Spring DAO
:
JDBCDAO
抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。
Spring DAO
的面向
JDBC
的异常遵从通用的
DAO
异常层次结构。
5
、
Spring ORM
:
Spring
框架插入了若干个
ORM
框架,从而提供了
ORM
的对象关系工具,其中包括
JDO
、
Hibernate
和
iBatisSQL Map
。所有这些都遵从
Spring
的通用事务和
DAO
异常层次结构。
6
、
Spring Web
模块:
Web
上下文模块建立在应用程序上下文模块之上,为基于
Web
的应用程序提供了上下文。所以,
Spring
框架支持与
Jakarta Struts
的集成。
Web
模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
7
、
Spring MVC
框架:
MVC
框架是一个全功能的构建
Web
应用程序的
MVC
实现。通过策略接口,
MVC
框架变成为高度可配置的,
MVC
容纳了大量视图技术,其中包括
JSP
、
Velocity
、
Tiles
、
iText
和
POI
。模型由
javabean
构成,存放于
Map
;视图是一个接口,负责显示模型;控制器表示逻辑代码,是
Controller
的实现。
Spring
框架的功能可以用在任何
J2EE
服务器中,大多数功能也适用于不受管理的环境。
Spring
的核心要点是:支持不绑定到特定
J2EE
服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同
J2EE
环境(
Web
或
EJB
)、独立应用程序、测试环境之间重用。
三
.
声明式事务
声明式事物管理意味着你无需在
Bean
中编写任何事物管理代码,只需将事物配置在
Bean
上就可以了。想要到达这个目的,最简单的方法就是使用代理——代理会拦截所有的方法的调用。如果方法名位于事物配置中,代理就是起到通知
(around)
的作用。它会在目标方法调用前开启事物,然后在一个
try/catch
块执行目标方法。如果目标方法正常完成,代理就会提交事物;如果目标抛出运行时异常,代理就会进行回滚。为了完成这些事情,代理需要配置好
PlatfromTransactionManager
。这是声明式事务管理的核心概念,其独特指出就是创建代理的方式不同。
事务的传播特性
1. PROPAGATION_REQUIRED(required):
如果存在一个事务,则支持当前事务。如果没有事务则开启(常用的配置)
2. PROPAGATION_SUPPORTS(supports):
如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
3. PROPAGATION_MANDATORY(mandatory):
如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4. PROPAGATION_REQUIRES_NEW(requires_new):
总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
5. PROPAGATION_NOT_SUPPORTED(not_supported):
总是非事务地执行,并挂起任何存在的事务。
6. PROPAGATION_NEVER(never):
总是非事务地执行,如果存在一个活动事务,则抛出异常
Spring
配置声明式事务:
*
配置
SessionFactory
*
配置事务管理器
*
事务的传播特性
*
那些类那些方法使用事务
具体配置如下
:
<!--
配置
SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<!--
配置事务管理器
-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--
事务的传播特性
-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice>
<!--
哪些类哪些方法使用事务
-->
<aop:config>
<aop:pointcut expression="execution(* com.biped.service.*.*(..))" id="transactionPC"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPC"/>
</aop:config>
<!--
普通
IOC
注入
-->
<bean id="userManager" class="com.biped.service.UserManagerImpl">
<property name="logManager" ref="logManager"/>
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="logManager" class="com.biped.service.LogManagerImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
四
.
事务配置方式
:
第一种
:
每个
bean
一个代理
第二种方式:所有
Bean
共享一个代理基类
第三种方式:使用拦截器
第四种方式:使用
tx
标签配置的拦截器
第五种方式:全注解
五
.
事务管理方式
1.annotation(
注解
)
2.xml
配置
(aop
技术
)
<!-- 1.
注解方式配置事务
-->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<!-- 2.xml
方式配置事务
.
利用
aop
技术
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* com.test.service..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
-->
六
.
注入方式
1.
通过
setter
方式
2.
构造方式
3.
注解方式
@Resource
@Autowired
两者的区别:
1. @Resource
标注是由
JDK
提供的,而
@Autowired
标注是由
Spring
提供的,因而
@Autowired
标注会与
Spring
紧密耦合,所以推荐使用
@Resource
标注;
2. @Resource
默认是按照名称来装配注入的,当找不到与名称匹配的
bean
才会按照类型来装配注入;
3. @Autowired
默认是按照类型装配注入的,假如想按照名称来转配注入,则需要结合
@Qualifier
一起使用;
4. @Resource
和
@Autowired
都可以用来标注字段或者
setter
方法。
七
.
什么是
Spring
------
开源的,控制反转(
Inversion of Control
)和面向切面的容器框架。
Spring
核心:
IOC
(控制反转)
-------
创建对象并且组装对象之间的关系。
IOC:
应用程序本身不负责依赖对象的创建和维护,依赖对象的创建和维护是由外部容器负责的。这样控制权就由应用程序转移到了外部容器。控制权的转移就是所谓的反转。
依赖注入:
Dependency Injection
:在运行时由外部容器将依赖对象注入到组件中。
八
.
为什么使用
Spring
1
:降低组件之间的耦合度,实现各层之间的解耦
2
:可以使用容器提供的众多服务。如:
--
事务管理服务
--JMS
--Spring core
核心服务
--
持久化服务
--
其他
3
:提供了单例模式支持。开发人员不需要自己编写实现代码
4
:提供了
AOP
技术。实现如:权限拦截,运行监控等功能
5
:提供了众多的辅助类。如
JDBC Template
,
HIbernate Template
6
:对主流的应用框架提供了集成支持。集成
Struts
,
JPA
,
Hibernate
九
. spring
的
7
个模块
spring
核心容器
(Core)
spring
上下文
springAOP
SpringDAO
SpringORM
springWeb
支持
struts
集成
springMVC
自带的
mvc
框架
十
. spring
实现的
2
种设计模式
单列模式:接受容器管理的
bean
,默认采用单态模式管理。
工厂模式:
spring
就是实例化和管理全部
bean
的工厂。
spring
的上下文也就是工厂,也被设计成单态的
十一
. Spring
实例化
bean
的三种方式
1
:默认使用类加载器
2
:使用静态工厂方法实例化
bean
对象
<bean id="
名称
" class="
工厂类
" factory-method="
工厂类中创建
bean
实例的方法
"/>
3
:使用实例工厂方法实例化
bena
对象
<bean id="
实例工厂名称
" class="
工厂类的路径
"/>
<bean id="
名称
" factory-bean="
实例工厂名称
" method="
实例工厂里边的创建
bena
对象的方法
"/>
十二
. Bean
的作用域
Singleton
Spring
容器只存在一个共享的
bean
实例,默认的配置。
<bean id="example" class="com.yz.bean.Example"/>
Prototype
每次对
bean
的请求都会创建一个新的
bean
实例。
<bean id="example" class="com.yz.bean.Example" singleton=”false”/>
两者如何选择?原则:所有有状态的
bean
都使用
Prototype
作用域,而对无状态的
bean
则应该使用
singleton
作用域。
十三
. Spring
的生命周期
bean
的实例化:
1
:当作用域范围为
singleton
时,在初始化
Spring
容易的时候实例化
bean
实例。
---1
:如果
lazy-init
的值为
true
,则为延迟
bean
的实例化,即在
Spring
容器启动时不实例化
bean
的对象
2
:当作用域范围为
prototype
时,在调用
Spring
的
getBean
的方法时实例化
bean
对象
注入依赖对象可以采用手工装配或者自动装配,在实际应用中建议采用手工装配。因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。
十四
.AOP
中的概念
Aspect
:
Aspect
声明类似于
Java
中的类声明,在
Aspect
中会包含着一些
Pointcut
以及相应的
Advice
。
Joint point
(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它
joint point
。
Pointcut
(切入点):表示一组
joint point
,这些
joint point
或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的
Advice
将要发生的地方。
Advice
(通知):
Advice
定义了在
pointcut
里面定义的程序点具体要做的操作,它通过
before
、
after
和
around
来区别是在每个
joint point
之前、之后还是代替执行的代码。
Weaving
(织入)
:
织入,指将通知插入到目标对象。
Target
(目标对象)
:
目标对象,指需要织入切面的对象。
Proxy
(代理对象)
:
代理对象,指切面织入目标对象之后形成的对象。
十五
.spring AOP
动态代理的过程
(1)
将切面使用动态代理的方式动态织入到目标对象(被代理类),形成一个代理对象;
(2)
目标对象如果没有实现代理接口,那么
Spring
会采用
CGLib
来生成代理对象,该代理对象是目标对象的子类;
(3)
目标对象如果是
final
类,并且也没实现代理接口,就不能运用
AOP
。
十六
.
配置过程:
(
1
)配置目标对象
(
2
)配置通知
(
3
)利用
ProxyFactoryBean
将通知织入到目标对象,形成一个动态代理对象
(
4
)客户端使用动态代理来访问目标对象的方法。
十七
.
关于
Spring
与
EJB
Spring
与
EJB3.0
之间的关系是竞争关系。
①
Spring
是一个开源的框架,而
EJB3.0
是一个标准(标准意味着将得到广泛的支持以及良好的兼容性),并且,采用
EJB3.0
,项目的后期维护得到了保证。
②
Spring
是一个轻量级框架,
EJB3.0
是一个重量级框架(完整的容器,包含所有的服务)。
③
Spring
的
IoC
,
AOP
集成了大量的开源框架,可扩展性良好。
EJB3.0
的可扩展性则完全依赖于新的容器。
④
Spring
对事务支持不如
EJB3.0
成熟,
Spring
对集群的兼容也不够。
⑤
Spring
与
EJB3.0
都是一个企业级开发框架,都支持声明式事务。
十八
.springMVC
常用注解
:
@Controller
负责注册一个
bean
到
spring
上下文中,
bean
的
ID
默认为类名称开头字母小写
,
你也可以自己指定
@RequestMapping
用来定义访问的
URL
,你可以为整个类
/
方法定义一个
@RequestBody
将
HTTP
请求正文转换为适合的
HttpMessageConverter
对象。
@ResponseBody
将内容或对象作为
HTTP
响应正文返回,并调用适合
HttpMessageConverter
的
Adapter
转换对象,写入输出流。
@CookieValue
获取
cookie
信息
@RequestHeader
获取请求的头部信息
十九
.
什么
springbatch
Spring Batch
是一个轻量级的,完全面向
Spring
的批处理框架,可以应用于企业级大量的数据处理系统。
Spring Batch
以
POJO
和大家熟知的
Spring
框架为基础,使开发者更容易的访问和利用企业级服务。
Spring Batch
可以提供大量的,可重复的数据处理功能,包括日志记录
/
跟踪,事务管理,作业处理统计工作重新启动、跳过,和资源管理等重要功能。
二十
.springbatch
的执行流程

每个
Batch
都会包含一个
Job
。
Job
就像一个容器,这个容器里装了若干
Step
,
Batch
中实际干活的也就是这些
Step
,
Step
主要是读取数据,处理数据,然后将这些数据存储起来
(ItemReader
用来读取数据,
ItemProcessor
用来处理数据,
ItemWriter
用来写数据
)
。
JobLauncher
用来启动
Job
,
JobRepository
是上述处理提供的一种持久化机制,它为
JobLauncher
,
Job
,和
Step
实例提供
CRUD
操作。
外部控制器调用
JobLauncher
启动一个
Job
,
Job
调用自己的
Step
去实现对数据的操作,
Step
处理完成后,再将处理结果一步步返回给上一层,这就是
Batch
处理实现的一个简单流程。
Struts:
一
.
Rest
-
什么是rest
REST
是
REpresentational State Transfer
的缩写(一般中文翻译为表述性状态转移)。一种体系结构。而
HTTP
是一种包含了
REST
架构属性的协议。在
REST
中所有东西都被看作资源。每一个资源都有一个
URI
和它对应。每个
REST
请求都是孤立的,请求中包含了所需的全部信息。
REST
服务端不存储状态。
REST
支持不同的通信数据格式,比如
XML
、
JSON
。
-
rest 的原则
URL
表示资源
HTTP
方法表示操作
GET
只是用来请求操作,
GET
操作永远都不应该修改服务器的状态。
服务应该是无状态的
WebService
一
.
什么是
webservice
是一个
SOA
的架构
,
它是不依赖与语言
,
不依赖于平台
,
可以实现不同的语言见的相互调用
,
通过
Internet
进行基于
http
协议的网络应用间的交互
.
WebService
实现不同语言间的调用
,
是依托于一个标准
,webservice
是需要遵守
WSDL/SOAP
规范的
.
通过标准的协议和接口
,
可以让不同的程序集成的一种
SOA
架构
.
二
.webservice
的优点
1.
跨平台的程序相互访问
2.
松耦合
3.
基于标准协议
三
.WebService
的基本原理
1.Service provider
采用
WSDL
描述服务
2.Service Provider
采用
UUDI
将服务的描述文件发布到
UDDI
服务器
3. Service Requestor
在
UDDI
服务器上查询并
获取
WSDL
文件
4. Service Requestor
将请求绑定到
SOAP
,并访问相应的服务。
四
.webservice
名词解释
JAXP(Java API for XML Parsing)
定义了在
Java
中使用
DOM, SAX, XSLT
的通用的接口。这样在你的程序中你只要使用这些通用的接口,当你需要改变具体的实现时候也不需要修改代码。
JAXM(Java API for XML Messaging)
是为
SOAP
通信提供访问方法和传输机制的
API
。
WSDL(Web Services Description Language)
是一种
XML
格式,用于将网络服务描述为一组端点,这些端点对包含面向文档信息或面向过程信息的消息进行操作。这种格式首先对操作和消息进行抽象描述,然后将其绑定到具体的网络协议和消息格式上以定义端点。相关的具体端点即组合成为抽象端点(服务)。
SOAP
即简单对象访问协议
(Simple Object Access Protocol)
,它是用于交换
XML
编码信息的轻量级协议。
UDDI (Universal Description, Discovery, and Integration)
的目的是为电子商务建立标准;
UDDI
是一套基于
Web
的、分布式的、为
Web Service
提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的
Web Service
注册,以使别的企业能够发现的访问协议的实现标准。
在用户能够调用
Web
服务之前,必须确定这个服务内包含哪些商务方法,找到被调用的接口定义,还要在服务端来编制软件,
UDDI
是一种根据描述文档来引导系统查找相应服务的机制。
UDDI
利用
SOAP
消息机制(标准的
XML/HTTP
)来发布,编辑,浏览以及查找注册信息。它采用
XML
格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。
五
.
什么是
SOA
面向服务的架构(
Service Oriented Architecture
,
SOA
)是表示所谓服务的自包含功能单元的一种软件设计原则和架构设计模式。
SOA
推崇松耦合、复用性和粗粒度的服务设计原则。在企业架构方面,
SOA
带来的好处包括对业务需求的敏捷交付和迅速反应,通过降低集成成本提高投资回报率,通过复用组件降低开放成本。企业架构一般使用企业服务总线
(ESB)
作为大型企业线上应用的集成层
六
.
应用集成方式有哪些
1.
共享数据库
2.
批量文件传输
3.
远程过程调用(
RPC
)
4.
通过消息中间件来交换异步信息(
MOM
)
七
.
应用集成可以采用的
Web
服务方式有什么?
SOAP WS
(
Simple Object Access Protocal
)
和
RESTful Web Service
(
REpresentational State Transfer
)
八
. SOAP WS
和
RESTful Web Service
之间有什么不同呢?
1.SOAP WS
支持既远程过程调用(例如,
RPC
)又支持消息中间件(
MOM
)方式进行应用集成。而
Restful Web Service
仅支持
RPC
集成方式。
2.SOAP WS
是传输协议无关的。它支持多种协议,比如,
HTTP(S)
、
Messaging
、
TCP
、
UDP SMTP
等等。而
REST
是协议相关的,只支持
HTTP
或者
HTTPS
协议。
3.SOAP WS
仅允许使用
XML
数据格式。定义的操作通过
POST
请求发送。其重点是通过操作名来获取服务,并将应用逻辑封装为服务。而
REST
方式则允许多种数据格式,而且由于
REST
方式采用标准
GET
、
PUT
、
PSOT
和
DELETE
方法,因此所有的浏览器都可以支持。其重点是通过资源名来获取服务,并将数据封装为服务。
AJAX
支持
REST
方式,它可以使用
XMLHttpRequest
对象。无状态
CRUD
操作(创建、读、更新和删除)更加适合这种方式。
九
. SOA
和
Web service
的区别是什么?
SOA
是一种软件设计准则,一种实现松耦合,高可复用性和粗粒度的
web
服务的设计模式。开发者可以选择任意协议实现
SOA
,例如,
HTTP
、
HTTPS
、
JMS
、
SMTP
、
RMI
、
IIOP
(例如,采用
IIOP
的
EJB
)、
RPC
等。消息可以采用
XML
或者数据传输对象(
Data Transfer Objects
,
DTOs
)。
Web Service
是实现
SOA
的技术之一。也可以不用
Web service
来实现
SOA
应用:例如,用一些传统的技术,像
Java RMI
,
EJB
,
JMS
消息等。但是
Web service
提供的是标准的平台无关的服务,这些服务采用
HTTP
、
XML
、
SOAP
、
WSDL
和
UDDI
技术,因此可以带来
J2EE
和
.NET
这些异构技术(
heterogeneous technologies
)之间的互操作性。
十
.
如果可以使用传统的中间件方式,例如,
RPC
、
CORBA
、
RMI
和
DCOM
,为什么还要选择
Web service
?
传统的中间件跟应用关系紧密,对应用的任何修改都可能会引起对应中间件的修改。因此这种方式下应用不好维护,复用性也比较差。一般情况下也无法支持异质系统(
heterogeneity
)。另外,采用这种方式应尽量避免互联网访问应用。还有,这种方式代价更高并且可用性差。
Web service
采用松耦合连接,即在客户端和服务器端之间提供了一个抽象层。这种松耦合应用可以减少维护成本并增加可复用性。
Web service
提供了一种基于
XML
和
Web
的新的中间件形式。
Web service
是语言和平台无关的,任何语言都可以用来开发一个
Web service
,并且部署到任何平台上,包括小型设备到大型超级计算机。
Web service
采用语言无关协议,例如
HTTP
,并且通过
Web API
来在不同的应用程序之间传输
XML
消息。
Web service
可以通过互联网访问,开销少并且可用性好。
十一
.
开发基于
SOAP
的
Web service
有哪些方式呢?
契约先行(也称为自顶向下,
contract-first
)方式:通过
XSD
和
WSDL
来定义
contract
,然后根据
contract
生成
Java
类;
契约后行(也称为自底向上,
contract-last
)方式:先定义
Java
类,然后生成约定,也就是从
Java
类得到
WSDL
文件。
Dubbo+zookeeper
-
dubbo的出现是为了解决什么问题
-
当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
-
当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系
-
接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
-
dubbo 是什么
Dubbo
是一个分布式服务框架,以及
SOA
治理方案。其功能主要包括:高性能
NIO
通讯及多协议集成,服务动态寻址与路由,软负载均衡与容错,依赖分析与降级等。
-
Zookeeper是如何完成注册的
保存了服务提供方和服务消费方的的
URI
(
dubbo
自定义的一种
URI
),服务消费方找到
zookeeper
,向
zookeeper
要到服务提供方的
URI
,然后就找到提供方,并调用提供方的服务。
-
Dubbo 在安全机制方面是如何解决的
Dubbo
主要针对内部服务,对外的服务,阿里有开放平台来处理安全和流控,所以
Dubbo
在安全方面实现的功能较少,基本上只防君子不防小人,只防止误调用。
Dubbo
通过
Token
令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。
Dubbo
还提供服务黑白名单,来控制服务所允许的调用方。
-
dubbo的工作原理

节点角色说明:
Provider:
暴露服务的服务提供方。
Consumer:
调用远程服务的服务消费方。
Registry:
服务注册与发现的注册中心。
Monitor:
统计服务的调用次调和调用时间的监控中心。
Container:
服务运行容器。
工作原理
:
服务运行容器启动
,
加载
,
运行服务提供者
,
在服务提供者启动适合
,
就向注册中心注册自己提供的服务
,
服务消费者在启动的时候
,
向注册中心订阅自己所需要的服务
.
注册中心返回服务提供者地址给消费者
,
如果有变更
,
注册中心将基于长连接推送变更数据给消费者
.
消费者从提供者地址列表中
,
基于软负载均衡算法
,
选一台提供者进行调用
,
如果调用失败
,
再选另一台调用
.
服务消费者和提供者
,
在内存中累计调用次数和调用时间
,
定时每分钟发送一次统计数据懂啊监控中心
.
支付系统开发
支付平台:往小说就是个中间件,可以帮助你转发各种付款,收款,查询的要求。但是做大了就是公司的资金出入口,负责公司和银行之间资金流向的桥梁,随着时代发展,电子商务飞速发展,第三方支付也是层出不穷,可以说几乎每个时刻都在突出新的支付类型,各个银行推出网上支付,代扣,代收付,这种便利的交易方式,使得我们可以不出门就可以东西,但是随这支付方式的增加,电子商务公司就需要把所有支付方式放在一个系统进行统一管理,这就是支付平台,我个人理解支付平台最大的功能,有效的系统的管理公司所有的资金流向,确保资金交易不会出错。即便出错才可以自我补救。
-
支付平台需要注意哪些?
1.
入口统一。而且不应经常变化,
无论收款,付款,查询,对账都应是一个入口(这也是我做了几种类型后才发现的。)入口统一的好处,集成方便,客户群只需要知道接口和参数便可方便集成
2.
支付渠道可以来回切换。支付平台的支付功能接口可以固定,譬如
(支付,代扣,转账)可以固定,但是选取那个银行接口应是可以切换的,这就需要将支付方式活配,客户可以指定那个银行进行支付,也可以不指定,我们根据客户的要求自动分配合理方案。
3.
支付数据存储方式应统一化。刚开始做的时候为每一个支付渠道,后来出现数据表泛滥,这也是弯路所有的支付渠道都有共同点,所以在数据库设计这里应该谨慎,必先出现表泛滥,应当将渠道统一化,个别的可以采用扩展表方式
4.
为客户提供补充处理。有些银行在支付过程中无法提供明确的结果回应,这就需要采用延时查询结果功能,大多采用定时处理进行。
5.
业务主流程要清晰。不应随意改变,建议采用控制反转。
6.
对于重复支付的控制。除了网上银行的方式我们无法控制,但是实时类支付应当做到尽量控制重复支付的情况
-
商户网站接入支付结果有几种方式
有两种方式
,
分别是通过浏览器进行跳转通知
,
通过服务器异步通知
浏览器跳转通知:这种方式主要是基于用户访问的浏览器,如果用户在银行页面支付成功后,直接关闭了页面,并未等待银行跳转到支付结果页面,那么商户网站就收不到支付结果的通知,导致支付结果难以处理。而且浏览器端数据很容易被篡改,而降低安全性。所以我们推荐技术人员开发时使用后端服务器通知做技术判断,而只将前台通知进行支付相关显示,不进行逻辑处理。
服务器异步通知:该方式是支付公司服务器后台直接向用户指定的异步通知
URL
发送参数,采用
POST
或
GET
的方式。商户网站接收异部参数的
URL
对应的程序中,要对支付公司返回的支付结果进行签名验证,成功后进行支付逻辑处理,如验证金额、订单信息是否与发起支付时一致,验证正常则对订单进行状态处理或为用户进行网站内入账等。
-
现在支付公司提供的结算周期模式
T+0
和
T+1
模式
T+1
模式时,即用户支付完毕后,支付公司将在第二天进行结算,商户即可将资金提取到自己的银行卡,或支付公司直接结算到约定的商户收款账户中。
T+0
的模式,则支付资金可以随时清算,并提现到商户银行卡。
-
收款流程
商户网站将支付信息提供给支付网关后,网站引导用户进入相关银行网关进行支付,完成后银行扣款,并将支付结果返回给第三方支付公司,支付公司收到结果后将为商户进行支付平台内的入账处理,等待结算。结算完成后,商户即可登录第三方支付平台进行提现,将资金通过第三方支付平台转入到自己的银行卡中。
-
开发流程
与支付公司签约后,网站将获得相关开商户号、密钥、支付网关以及开发文档。技术人员通过阅读文档,获取需要使用的相关数据参数,如商品名称、金额等,并通过约定的加密方式及密钥进行加密处理,将以
FORM
表单
POST
或
GET
的方式发送给支付公司提供的支付网关
URL
。
支付网关收到商户提供的相关参数后将进行数据处理及加密验证,如果数据合格且密钥验证成功,将引导用户进入各家银行选择页面,用户在选择自己使用的银行后,将进入相关银行的支付网关进行支付。
用户在银行网关成功付款后,银行进行扣款,并将支付结果回传给支付公司,支付公司收到银行的结果,同样进行签名验证,并将支付结果信息传递给商户网站。
支付公司将支付结果传递给商户网站也是通过
FORM
表单的方式,只是该数据传递属于服务器后端处理的。商户网站向支付公司发起支付请求传递支付相关参数时,就包含一个或两个
URL
,用于指定接收支付结果的
URL
中。
-
有几种接入方案
两种接入方案
.
直接与银行对接与通过中间公司间接与银行对接
直接与银行对接
优缺点
:
因为直接与银行进行财务结算
,
交易资金结算比较安全
,
适合资金流量比较大的企业
,
这种方案适合于
:
每月结算金额百万以上的企业
.
缺点
:
开发工作量比较大
,
而且银行会不定期升级系统交易系统
,
随着银行系统的升级
,
企业也需要做相应改动
,
所以维护工作量比较大
,
而且企业每年还需要向银行交纳一定数量的接口使用费
.
通过中间公司与银行对接
优点
:
开发工作量少
,
因为使用的是中间企业提供的接入规范
,
所以银行升级系统
,
不需要企业做相应修改
,
除非中间企业的接入规范发生了改变
,
企业才作相应修改
.
相对前一种接入方案
,
这种方案的维护工作量比较少
,
因为只与一家企业对接
,
所以接入费用相对比较低
,
这种方案适合于
:
每个月结算金额在几十万以下的中小企业
.
缺点
:
因为是与中间企业进行资金结算
,
目前所有中间企业都是私企
,
资金安全是一个大问题
.
-
中间支付公司有哪些
首信易支付
每年需要交纳一定的接口费用
,
并且从交易金额中扣除
1%
的手续费
,
当当网
,
红孩儿
,
京东商城使用了首信易支付
易宝支付
接入免费
,
只从交易金额中扣除
1%
的手续费
.
例如
E
网往
,
巴巴运动网
-
易宝支付接入规范
MD5-hmac
Hmac
是一种秘密的密钥验证算法
.Hmac
提供的数据完整性和源省份验证完全取决于密钥分配范恩
,
如果只有发起者和接收者知道
Hmac
密钥
.
这么就对两者间发送的数据提供了源身份验证和完整性保证
.
StringBUffer sValue = new StringBuffer();
sValue.append(“tanghuan”);
sValue.appernd(“012345”);
String hmacMD5 = DigestUtil.hmacSign(sValue.toString(),”123456”);
-
易宝的支付流程
通过
http
请求方式像易宝支付网关发起一个支付请求
,
就是向
https://www.yeepay/.com/app-merchat-proxy/node
发起请求
,
请求可以是
get
或
post
方式提交
,
页面采用
GBK/GB2312
编码
.
易宝支付网关对企业发来的数据使用用户的密钥生成
MD5-hmac
码
,
然后跟企业发来的
MD5-hmac
码比较是否相同
,
如果相同即把请求转发到银行网关
,
当用户支付完成后
,
银行网关会引导用户的浏览器重定向到易宝支付网关
,
然后易宝支付网关再引导用户的浏览器重定向到企业提供的
url
-
给易宝支付网关发送的数据
业务类型
,
商户编号
,
商户订单号
,
支付金额
,
交易币种
,
商户接收支付成功数据的地址
,
商户扩展信息
,
银行编码
,
应答机制
(0—200
状态
成功
;1—
返回
success
字符串
),
商品名称
,
商品种类
,
商品描述
,
送货地址
(
后四个可选
)
十一
.
使用易宝支付常见问题
问题一:
请求查询绑卡信息的时候,报
{"error_code":"600000","error_msg":"illegal request"}
解决方案:
与易宝沟通,易宝说我们的测试服务器的
ip
必须在易宝那边报备,才不会出现这个问题。
问题二:
在本地环境中,前台回调地址可以接收到,但是后台异步通知地址始终接受不到?
解决方案
:
后台异步通知地址必须是外网可以访问的,所以必须在测试服务器上面进行,才能接收到。
十二
.
支付接口中的异步通知和同步通知的区别
1
异步通知和同步通知都需要有回调地址,如果没有回调地址,易宝支付平台是没有任何回调的。
2
异步通知和同步通知,如果是易宝支付平台自动回调的话,那么回调地址必须能够公网访问。
3
同步通知:商户服务器发起请求,易宝支付平台处理完成之后,通过浏览器跳转的方式,通知我们交易完成或者失败。
异步通知:商户服务器发起请求,易宝支付平台处理完成后,不以浏览器跳转的方式通知商户,而是服务器与服务器之间通信,将处理的结果通过我们的异步回调地址通知我们,这时候我们会按照事先和易宝平台协定的方式回应易宝支付,如果没有回应易宝支付会隔断时间再以服务器与服务器之间通信的方式,通知我,我只有按照商定的方式返回给他才行。
十三
.
很多时候我们登陆需要验证码,一个用户对应一个验证码,
1000
万个用户对应
1000
万个验证码,那么如何知道这个验证码是这个用户,那个验证码是那个用户的呢?
解决方案:
其实每生成一个验证码,会生成
seesion
存储,这时候会在浏览器生成一个
cookie
来存储
seesionid
,这个
sessionid
可以帮助服务器找到合适的
session
文件。
Nginx
一
.
什么是
Nginx
Nginx
是一个非常优秀的
HTTP
服务器
,
由于其并发能力强
,
并且体积很小
,
所以被称为轻量级
http
服务软件
.nginx
不单可以作为强大的
web
服务器
,
还可以作为一个反向代理服务器
.
而且
nginx
还可以按照调度规则实现动态、静态页面的分离,可以按照轮询、
ip
哈希、
URL
哈希、权重等多种方式对后端服务器做负载均衡,同时还支持后端服务器的健康检查。
二
.
如何配置负载均衡
在
http
节点里添加
:
#
定义负载均衡设备的
Ip
及设备状态
upstream myServer {
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
}
在需要使用负载的
Server
节点下添加
upstream
每个设备的状态
:
down
表示单前的
server
暂时不参与负载
weight
默认为
1.weight
越大,负载的权重就越大。
max_fails
:允许请求失败的次数默认为
1.
当超过最大次数时,返回
proxy_next_upstream
模块定义的错误
fail_timeout:max_fails
次失败后,暂停的时间。
backup
:
其它所有的非
backup
机器
down
或者忙的时候,请求
backup
机器。所以这台机器压力会最轻。
-
使用nginx常出现什么问题
-
session不同享,登陆状态不一致
2.
-
如何实现多台服务器之间的session共享
1
、不使用
session
,换用
cookie
session
是存放在服务器端的,
cookie
是存放在客户端的,我们可以把用户访问页面产生的
session
放到
cookie
里面,就是以
cookie
为中转站。你访问
web
服务器
A
,产生了
session
然后把它放到
cookie
里面,当你的请求被分配到
B
服务器时,服务器
B
先判断服务器有没有这个
session
,如果没有,再去看看客户端的
cookie
里面有没有这个
session
,如果也没有,说明
session
真的不存,如果
cookie
里面有,就把
cookie
里面的
sessoin
同步到服务器
B
,这样就可以实现
session
的同步了。
说明:这种方法实现起来简单,方便,也不会加大数据库的负担,但是如果客户端把
cookie
禁掉了的话,那么
session
就无从同步了,这样会给网站带来损失;
cookie
的安全性不高,虽然它已经加了密,但是还是可以伪造的。
2
、
session
存在数据库(
MySQL
等)中
PHP
可以配置将
session
保存在数据库中,这种方法是把存放
session
的表和其他数据库表放在一起,如果
mysql
也做了集群了话,每个
mysql
节点都要有这张表,并且这张
session
表的数据表要实时同步。
说明:用数据库来同步
session
,会加大数据库的
IO
,增加数据库的负担。而且数据库读写速度较慢,不利于
session
的适时同步。
3
、
session
存在
memcache
或者
redis
中
memcache
可以做分布式,
php
配置文件中设置存储方式为
memcache
,这样
php
自己会建立一个
session
集群,将
session
数据存储在
memcache
中。
说明:以这种方式来同步
session
,不会加大数据库的负担,并且安全性比用
cookie
大大的提高,把
session
放到内存里面,比从文件中读取要快很多。但是
memcache
把内存分成很多种规格的存储块,有块就有大小,这种方式也就决定了,
memcache
不能完全利用内存,会产生内存碎片,如果存储块不足,还会产生内存溢出。
4
、
nginx
中的
ip_hash
技术能够将某个
ip
的请求定向到同一台后端,这样一来这个
ip
下的某个客户端和某个后端就能建立起稳固的
session
,
ip_hash
是在
upstream
配置中定义的:
[html] view plaincopy
在
CODE
上查看代码片派生到我的代码片
upstream nginx.example.com
{
server 192.168.74.235:80;
server 192.168.74.236:80;
ip_hash;
}
server
{
listen 80;
location /
{
proxy_pass
}
}
互联网开发需要掌握的知识
:
http
HTTP
协议(
HyperText Transfer Protocol
,超文本传输协议)是用于从
WWW
服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示
(
如文本先于图形
)
等。
HTTP
是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。
HTTP
是一个无状态的协议。
设计模式
:
Spring
中使用到的设计模式
:
1.
工厂方法(
Factory Method
)
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
Factory Method
使一个类的实例化延迟到其子类。
spring
中的
FactoryBean
就是典型的工厂方法模式。如下图:

2.
单例(
Singleton
)
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
spring
中的单例模式完成了后半句话,即提供了全局的访问点
BeanFactory
。但没有从构造器级别去控制单例,这是因为
spring
管理的是是任意的
java
对象。
3.
适配器(
Adapter
)
将一个类的接口转换成客户希望的另外一个接口。
Adapter
模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
spring
中在对于
aop
的处理中有
Adapter
模式的例子,见如下图:

由于
Advisor
链需要的是
MethodInterceptor
对象,所以每一个
Advisor
中的
Advice
都要适配成对应的
MethodInterceptor
对象。
4.
代理(
Proxy
)
为其他对象提供一种代理以控制对这个对象的访问。
从结构上来看和
Decorator
模式类似,但
Proxy
是控制,更像是一种对功能的限制,而
Decorator
是增加职责。

spring
的
Proxy
模式在
aop
中有体现,比如
JdkDynamicAopProxy
和
Cglib2AopProxy
。
5.
观察者(
Observer
)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

spring
中
Observer
模式常用的地方是
listener
的实现。如
ApplicationListener
。
6.
策略(
Strategy
)
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
应用地方
:
第一个地方,加载资源文件的方式,使用了不同的方法,比如:
ClassPathResourece
,
FileSystemResource
,
ServletContextResource
,
UrlResource
但他们都有共同的借口
Resource
;第二个地方就是在
Aop
的实现中,采用了两种不同的方式,
JDK
动态代理和
CGLIB
代理;
7.
模板方法(
Template Method
)
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
Template Method
使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

Template Method
使用的模板方法模式
这里想要探讨另一种对
Template Method
的理解。
spring
中的
JdbcTemplate
,在用这个类时并不想去继承这个类,因为这个类的方法太多,但是我们还是想用到
JdbcTemplate
已有的稳定的、公用的数据库连接,那么我们怎么办呢?我们可以把变化的东西抽出来作为一个参数传入
JdbcTemplate
的方法中。但是变化的东西是一段代码,而且这段代码会用到
JdbcTemplate
中的变量。怎么办?那我们就用回调对象吧。在这个回调对象中定义一个操纵
JdbcTemplate
中变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。然后我们再传入这个回调对象到
JdbcTemplate
,从而完成了调用。这可能是
Template Method
不需要继承的另一种实现方式吧。
合道金融项目
:
合道金融项目
主要功能和定位是小额
p2p
借款业务的线下核心管理系统
,
它的功能包括管理模块
,
功能区
,
财富流程
,
抵押借款流程
,
系统批处理模块
等功能模块
.
提供给业务人员和风控人员进行统一协同工作
,
便于总比对各机构与部门的规划管理
.
采用
Web
系统主流框架
Struts2,spring,mybatis
提高系统的开发效率
,
简化数据操作统一规范开发标准
.
为降低服务维护成本
,
提高稳定性与数据安全性服务器采用阿里云主机
.
我所负责负责财富端流程和借款客户抵押借款流程审批功能的开发;负责合同管理模块的开发
;
财富端流程的需求是为出借客户提供出借申请网银支付
,
提前撤资等投资理财的需要
,
为公司提供申请信息录入
,
撮合匹配
,
回款确认
,
金额明细等一些完整的理财流程
.
它依赖于第三方支付易宝支付
,
借款申请
,
流程模块
.
申请好生成规范为
L+
机构
12
位
+
时间
8
位
+
序号
4
位
.
抵押借款流程的需求是为借款客户提供借款申请
,
还款还息等借款需要
,
为公司提供申请信息录入
,
撮合匹配
,
风险审核
,
放款确认
,
收支明细等一系列完整的借款流程
.
它依赖于第三方支付
,
出借申请
,
流程模块
.
申请号生成规范
B+
机构
12
位
+
时间
8
位
+
序号
4
号