spring 主要用途:
1. 用来整合其它框架
2. 提供业务层的声明式事务控制
所谓声明式事务控制,就是通过配置文件或注解的方式来实现事务控制
相对于编程式事务控制来说
================================= 分层时的耦合问题 ==================================
1. 了解工厂模式
2. spring 框架实现了工厂模式
service实现,dao实现交给spring管理
1) IOC 控制反转 Inversion of Controll
MyServlet extends HttpServlet
它的创建,和service方法的调用, 都是由tomcat服务器(servlet 容器)来处理
Dao的实现类, service实现类, 由spring(容器)来创建,或是调用其中某些方法
容器,指一个运行环境,某些类的创建和销毁受到容器管理
所谓的控制反转,就是指将某些类的创建、销毁、某些方法的调用,交由容器进行处理
2) AOP
3. 使用spring 的控制反转
步骤1:添加jar包
6 个:
spring-beans-...
spring-context-...
spring-context-support
spring-core
spring-expression
commons-logging
步骤2:
配置文件,对配置文件的名字和位置没有要求,格式为
xsi:schemaLocation="https://www.doczj.com/doc/c18932816.html,/schema/beans
https://www.doczj.com/doc/c18932816.html,/schema/beans/spring-beans.xsd ">
步骤3:
将 dao, service, action等类交给spring进行管理
spring相比传统工厂的优点:
使用工厂类时,仍需要用工厂类去主动获取产品;
使用了spring后相对于工厂的提高在于,只需要被动接收由spring生产的产品即可
给属性赋值的控制权也交给了spring,体现了控制反转的思想
传统的servlet容器 和 spring容器都体现了控制反转的思想。
传统的servlet容器,不负责建立类与类之间的依赖关系
spring容器,不仅要将dao,service交由spring管理,还要负责建立类与类之间的依赖关系
依赖注入 dependency inject DI (建立依赖关系的过程)
1) 建立了set方法,通过set方法建立依赖关系
2) 通过构造方法建立依赖关系
4. 常用配置
4.1 单例与多例 (*)
受 spring 管理的bean,默认都是“单实例”的,在同一个spring容器内是单例的
以前讲的单例模式,是在同一个jvm是单例的
singleton 单例
prototype 多例
例子:struts2 中的action在spring中需要配置为多例
4.2 初始化与销毁方法 (了解)
thod="销毁方法">
初始化方法会在类被实例化后只调用一次
销毁方法在spring容器关闭时调用一次
4.3 lazy-init="true" 延迟初始化 (了解)
spring会在容器创建时就创建每个bean的单实例
4.4
// 根据id进行匹配
UserDao dao1 = (UserDao) spring2.getBean("userDao");
UserDao dao2 = spring2.getBean("userDao", UserDao.class);
// 根据类型匹配, 限制:不能存在多个同类型对象,否则会有歧义
UserDao dao3 = spring2.getBean(UserDao.class);
4.5 构造方法注入
4.6 值注入
int
boolean
list
map
数组
properties
---------------------------
class
Resource spring 独有的 代表了一个文件
绝对路径 d:/abc/aa.txt file:d:/abc/aa.txt
类路径 classpath:包/包/aa.txt
http://主机名:端口号/aa.txt http://...
5. 实际例子
5.1 使用独立的连接池实现
Tomcat 提供的连接池实现 -- DBCP 连接池 (Pool)
C3P0
proxool
对连接池来讲:
会有一些可能导致池中的连接无效(网络问题,或是数据库连接超时)
===========================================================================================
spring 回顾
用途:整合,声明式的事务管理
特点:
IOC(控制反转), DI(依赖注入)
IOC:将创建和管理对象的权利交给spring容器
DI:spring还会管理对象之间的依赖关系
常见依赖注入方法:set方法注入,构造方法注入
AOP
配置文件:
init-method="" destory-method="" lazy-init="">
map =>
list =>
properties
=>
Resource
=> file: 绝对路径
=> classpath: 类路径
spring 容器对应的接口:
ApplicationContext.getBean("bean的唯一标识");
==========================================================================================
1. 已经存在的类交给spring管理
1) java.util.Date
2) java.util.Calendar
它是一个抽象类,是通过一个静态方法(工厂方法)来创建此类的实例的
3) java.sql.Date
ctor-arg>
2. 利用spring的工厂接口来构造对象 (*)
2.1 要实现一个FactoryBean<产品>接口
2.2 要实现的方法:
a. getObject 用来生产产品的方法
b. getObjectType 返回的是产品的类型
c. isSingleton 产品是单例还是多例
getBean("唯一标识") 返回的是工厂生产的产品
getBean("&唯一标识") 返回的是工厂自己
2.3 实际例子
要跟hibernate整合, spring提供了 SessionFactory 的工厂类,用来生产sessionFactory
需要增加以下jar包
spring-tx..
spring-jdbc..
spring-orm...
以及hibernate所需jar包
LocalSessionFactoryBean
如果是注解映射:
如果使用原始的hibernate.cfg.xml :
======================================= day2 下午 ========================================
1. 值注入时的类型转换(了解)
java.util.Date
如果希望spring自动做字符串=> 到某一特殊类型的转换,需要加一个转换器类
转换器类需要继承 PropertyEdito
rSupport 父类
属性 转换器 支持
重写 setAsText(String 待转换的字符串) {
完成转换操作;
setValue(转换结果);
}
2. PropertyPlaceholderConfigurer (*)
配置完毕后,凡是用到值注入的地方 ${properties文件中的key}
都可以用properties文件中的实际值来替换
3. 反射
类 也是一个对象, 好比是模子
对象 是类生产出来的东西
package day2
public class User {
}
得到类对象的方法:
a. User.class
b. new User().getClass()
c. Class.forName("https://www.doczj.com/doc/c18932816.html,er") 反射调用得到类对象
另一种创建对象实例的方法:
Class c = Class.forName("https://www.doczj.com/doc/c18932816.html,er");
c.newInstance(); 等价于 new User();
====================================== day 3 ================================================
AOP Aspect Oriented Programming 面向切面编程
代理模式:
代理类是程序员自己写的,称为静态代理, *.java => javac编译 => *.class
动态代理: 在程序运行时生成代理类的二进制代码 *.class 不经过编译
动态代理的原理:(难点)
跟面向切面编程相关的概念
Target 目标对象
Proxy 代理对象
在代理对象invoke中执行的额外操作,称为通知 Advice
事务算一种通知
通知有多种类型:
在目标对象方法前执行的通知:前置通知 MethodBefore
在目标对象方法正常执行完毕:AfterReturning
在目标对象方法出现异常: AfterThrowing
像事务这种在目标对象方法执行前后都会执行操作的:Around 环绕通知
切入点, 规定了哪些类的哪些方法需要执行通知操作 Pointcut
切面 Aspect(Advisor) = Advice + Pointcut
作用: 在正常的业务逻辑之外,增加额外的通知处理, 每个通知类相对独立通用
例如,有事务通知类,有权限检查通知类,日志记录通知类...
spring中运用面向切面编程
步骤1:加入jar包
spring-aop
spring-aspects
aopalliance-1.0.jar
aspectjrt-1.7.4.jar
aspectjweaver-1.7.4.jar
步骤2:修改spring配置文件头, 新增aop的命名空间
xmlns:tx="https://www.doczj.com/doc/c18932816.html,/schema/tx"
xmlns:xsi="http://www.w3.o
rg/2001/XMLSchema-instance"
xsi:schemaLocation=
"https://www.doczj.com/doc/c18932816.html,/schema/beans
https://www.doczj.com/doc/c18932816.html,/schema/beans/spring-beans.xsd
https://www.doczj.com/doc/c18932816.html,/schema/aop
https://www.doczj.com/doc/c18932816.html,/schema/aop/spring-aop.xsd
https://www.doczj.com/doc/c18932816.html,/schema/tx
https://www.doczj.com/doc/c18932816.html,/schema/tx/spring-tx.xsd ">
步骤3. 实现通知类
对于前置通知需要实现 MethodBeforeAdvice接口
并在spring中配置此通知类
步骤4. 定义切入点
步骤5:
步骤5:使用
spring容器.getBean("目标对象id"); 返回的是已经是代理对象
代理对象调用时,会调用通知类,以及目标对象的相应方法
作业:
用户 角色 权限
zhangsan 管理员 添加商品
修改商品
查询商品
wangwu
lisi 普通用户(会员) 查询商品
用户和角色是多对一
角色和权限是多对多 (两个实体)
======================================== day4 ======================================
spring 和 hibernate 整合,添加声明式事务支持
步骤:
1) 实体类,映射文件
2) Dao
依赖于sessionFactory
sessionFactory又依赖于dataSource
dao层实现需要用sessionFactory中 getCurrentSession()来获得Session对象
3) service
依赖于dao
4) 配置声明式事务
理事务的方法不一样 -->
=================================== day 4 下午 ==========================================
1. 什么时候事务会回滚 (*)
默认情况下:
当异常是 RuntimeException或是RuntimeException的子类时,事务才会回滚
检查异常 Exception不会导致事务回滚
service如果捕捉了异常,没有继续抛出,那么仍会导致事务提交
2. readOnly 只读事务 (了解)
jdbc 的一项特征, 如果能确保事务运行过程中,不做增删改,设为只读事务能够提高效率
不同数据库驱动对只读事务的支持有差别
3. 事务隔离级别 (了解)
主要目的,来保证同一次事务中数据的读一致性
ISOLATION_DEFAULT 采用数据库默认的隔离级别
ISOLATION_READ_COMMITED 读提交 能够避免 脏读
ISOLATION_REPEATABLE_READ 可重复读 能够避免 不可重复读
oracle中没有此隔离级别,他用的是...for update这种悲观锁
ISOLATION_SERIALIZABLE 序列化读 能够避免 幻读
一个查一个修改 id=1 amount=3000 不可重复读
客户1 客户2
select * from 表 where id=1
3000
update 表 set amount=4000 where id=1
commit;
select * from 表 where id=1
4000
一个查一个增 幻读
客户1 客户2
select count(*) from 表
10
insert into 表 ...
select count(*) from 表
11
=================== 日志处理 =============================
slf4j-api 日志接口
slf4j-log4j12 桥梁包
log4j-1.2.17 日志的实现, logback,
log4j 2, jdk日志实现
日志配置文件, 位置src下
log4j.properties
log4j.xml
例如:DailyRollingFileAppender 目标是文件
ConsoleAppender 目标是控制台
日志级别 从低到高: trace, debug, info, warn, error
级别越高显示的内容越少,级别越低显示的内容越多越详细
记录程序的运行流程
用来调试程序
作业:
用户,角色,权限的service ,dao 写好, service上加事务控制
================================= day 5===================================================
spring 与struts2 的整合
1. 将action类配置到spring中,并且该action的scope是prototype
2. 加入一个struts2-spring-plugin.jar
plugin 插件
作用:让struts识别
例如:
3. 配置spring容器
导入spring-web.jar
spring是将spring容器创建好放入 ServletContext (application作用域)
在spring中解决hibernate延迟加载的问题
方法1: 给关系属性加lazy='false'
方法2:使用连接查询
"select distinct r from Role r inner join fetch r.permissions"
方法3:OpenSessionInViewFilter =>
延长session的打开时间,直到view的内容都显示完毕,在关闭session
a. 请求经过此过滤器,总会首先打开一个hibernate的session
设一个标记为true
b. 再经过事务通知时,事务通知类会检查此标记,那么事务结束时不会关闭session
c. 进入jsp,将延迟加载的数据查询并显示出来
d. 回到过滤器时,关闭session
=======================================================================================
spring 和 hibernate 整合的另一种方法
方法1:在dao层注入的是SessionFactory
缺点: dao层无法直接测试,必须配合s
ervice增加了事务控制后来测试
方法2:在dao层注入 HibernateTemplate 模板类
优点:可以直接测试dao层
hibernateTemplate.save()
hibernateTemplate.update()
hibernateTemplate.delete()
hibernateTemplate.get()
hibernateTemplate.find(hql语句) => 返回list集合
from User where username = ? and password = ?
hibernateTemplate.find(hql语句, "zhangsan", "123");
缺点:
缺少查询单个记录的方法
=======================================================================================
使用注解来完成 Spring 依赖注入以及事务管理
@Component("beanid") =>
加了此注解的类,是受spring管理的类
@Autowired =>
加在属性上,默认根据类型进行匹配
@Transactional 支持事务的
可以加在方法上
可以加在类上, 表示此类的所有方法都应用事务
对于前两个注解:需要加
对于后一个注解:需要加
对于action类,需要多加一个@Scope("prototype")
============================== day6 ================================================
自定义注解
@Overried
@Component
@Autowired
1) 定义注解能加的位置:
@Target(ElementType.TYPE) 表示注解能加在类上
@Target(ElementType.METHOD) 表示能加在方法上
@Target(ElementType.FIELD) 表示能加在field(属性)上
@Target({ElementType.TYPE, ElementType.METHOD})
表示既能加在类上,也能加在方法上
2) 什么时候能够读取到注解
@Retention(RetentionPolicy.SOURCE) 注解仅在源代码有效
@Retention(RetentionPolicy.CLASS) 注解在代码编译为.class文件后有效
@Retention(RetentionPolicy.RUNTIME) 注解在代码运行时有效
给业务逻辑方法添加权限控制
步骤1: 添加一个自定义注解
步骤2: 使用注解将业务方法和权限联系起来
步骤3: 编写权限检查的通知类
步骤4: 为权限通知类配置切面
============================================================================
struts2 - hibernate - spring - ajax+jquery
maven 用途
1) 管理jar包
pom.xml
不仅下载hibernate的包,还会将它所依赖的jar一起下载下来
2) 项目自动构建
执行批量单元测试
执行编译、单元测试、打包、部署等操作
tomcat服务器在linux 环境
tomcat目标/webapps/spring2.war
open ssh 它是一个远程连接linux服务器的工具
主机名,端口号,用户名,密码
winscp 图形化界面工具
SecureCRT 图形化界面工具
设计模式:
单例模式
分饿汉式和懒汉式
懒汉式要用内部类实现
简单工厂模式
配合接口降低层与层之间的耦合
spring容器比普通工厂更为先进,工厂模式主动调用工厂获得实现类
spring中只需要被动接受容器提供的实现类
代理模式
hibernate 关系属性的延迟加载
spring 中aop模式的实现
======================================================================================
spring-data => jpa
=> mongodb
=> redis