spring总结
Spring学习(详细)
Spring 概念
1. spring是开源的轻量级框架 轻量级:框架使用不需要依赖其他技术。可独立使用。 2. Spring是一站式框架 (1) Spring在javaEE三层结构中,每一层都提供了不同的解决技术,则称为一站式。 --web层:springMVC --service层:spring的IOC --dao层:spring的JdbcTemplate 3. Spring核心主要两部分: (1)aop:面向切面编程 --扩展功能不是修改源代码实现。 (2)Ioc:控制反转 --比如有一个User类,在类中有方法add();(不是静态方法),通常我们调用里面的方法需要创建类对象,需要new关键字来创建。 例: User user= new User(); user.add(); --ioc创建对象不需要通过上述方式实现,而是交给spring配置创建类对象。 4. spring版本 Spring4.x |
Spring核心:IOC
1. 控制反转(IOC)就是吧创建对象交给spring容器进行管理。
2. IOC操作两部分: (1):IOC的配置文件方式 (2):IOC的注解方式 |
Ioc底层原理
1. ioc底层原理实用技术 (1)xml配置文件 (2)dom4j解析xml (3)工厂设计模式 (4)反射机制 2.画图分析IOC实现原理
|
IOC入门案例
第一步:导入jar包 (1)解压资料zip文件 解压后Jar包特点:
分别是:jar包 文档 源码 最基本共能只需要这些核心jar包: (2)导入日志jar包 (3)共需jar包: 第二步:创建类对象,在类里创建方法 (1)最原始做法
第三步:创建spring配置文件,配置创建类 (1)spring核心配置文件名称和位置不是固定的 ----建议放在src下面,官方建议名称:applicationContext.xml (2)引入schema约束
(3)配置对象创建
第四步:写测试类
|
Spring的bean管理(xml配置文件)
bean实例化的三种方式
1. 概念:所谓bean实例化就是在spring里面通过配置文件创建对象 2. Bean实例化三种方式: 第一种:使用类的无参构造创建 上一个IOC入门案例用的就是这种方式。 注:图片中意思是:类中没有有参构造时,无参构造是默认不写的,但是真实存在,当加上一个有参构造时,无参构造就必须声明。 第二种:使用静态工厂创建 (1)创建静态方法,返回类对象
第三种:使用实例工厂创建 (1)创建的不是静态方法,返回类对象
|
Bean标签的常用属性
(1)id属性:id表示起的名字,可以任意命名。 -----id属性值,不能包含特殊符号,_ ,$ ,#等 -----代码中根据id值得到配置的对象。 (2)class属性:创建对象所在类的全路径
(3)name属性:功能和id属性一样,只是可以加入特殊符号,现在已经不用了,这是遗留问题,比如struts1里面有很多action写法可以写一些符号,name是整合他们而用到的属性,struts2中没有 (4)scope属性:(了解) |
属性注入
1. 创建对象时,向类里面属性里面设置值 2. 属性注入的方式(三种方式) (1)set注入 (2)有参构造注入 (3)接口注入
3. 在spring框架之内,支持前两种方法 (1)set方法 (2)有参构造 |
使用有参构造注入属性
|
使用set方法注入属性
|
注入对象类型的属性
1. 创建service类和dao类 (1)在service得到dao对象 2. 具体实现过程 (1)生成UserDao的set方法
|
P名称空间注入
同一个标签中不能有相同的属性,所以引入命名空间 第一步:建立P命名空间引用
引入后才能操作
|
复杂类型属性注入
1. 数组 2. List集合 3. Map集合 4. Properties 都将他们定义在Person类中:
|
IOC和DI区别
(1)IOC控制反转,把对象创建交给spring进行配置 (2)DI依赖注入,创建对象过程中,向类里面的属性中设置值。 (3)两者之间关系:依赖注入不能单独存在,需要在IOC的基础之上完成操作。 |
Spring的bean管理(注解)
注解
1. 代码里面的特殊的标记,使用注解可以完成功能 2. 注解写法@注解名称(属性名称=属性值) 3. 可以使用在类上面 方法上面 属性上面 |
Spring注解开发准备
1. 导入jar包 (1)导入基本的jar包 (2)导入aop的jar包 2. 创建类,创建方法 3. 创建spring配置文件,引入约束
|
注解创建对象
1. 在创建对象的类上面使用注解实现
|
注解注入属性
1. 创建service类,创建dao类,在service得到dao对象 (1)创建dao和service对象,在service类里面定义dao类型属性
|
配置文件和注解混合使用
1. 创建对象操作使用配置文件方式实现
2. 注入属性操作使用注解方式实现(要开启注解扫描的配置)
|
自我拓展全配置文件实现上述操作
配置文件内容
| |||
代码内容
|
Spring核心:AOP
Aop相关概念
1. aop:面向切面编程(面向方面),扩展功能不修改源代码实现 |
AOP原理
1. 画图分析 (1)纵向演变
(2)横向演变
|
Aop操作相关术语
joinpoint(连接点):类里哪些方法可以被增强,就被称为连接点。(delete,add,等) pointcut(切入点):类里有很多方法被增强,比如在实际操作中,只增强了类中的add和update方法,实际增强的方法就是切入点(通俗点:通过切入的表达式筛选需要切入的业务方法) advice(通知/增强):增强的逻辑,称为增强。比如拓展一个日志共功能,这个日志功能成为增强;
如果add()方法为例: 在方法之前执行 在方法之后执行 方法执行异常 在后置之后 在方法之前和之后来执行称为环绕 Aspect(切面):把我们的增强应用到具体的方法上面,过程称为切面 (把增强应用到切入点的过程)
|
springAOP操作
1. 使用Aspectj实现aop操作
(1)本身不是spring的一部分,和spring一起使用,进行aop操作。 2. 使用aspectj实现aop有两种方式 (1)基于aspectj的xml配置 (2)基于aspect的注解方式 |
Aop操作准备
1. jar包
AOP功能是增强类中的方法(某个或者某些) 2. 引入约束
|
AOP增强配置方式
1. Book类
2. StrongBook类
第一步: 使用表达式配置切入点(实际增强的方法)指定切入点
表达式格式: execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>) (1) execution(* com.game79.aop.Book.add(..))
(2) execution(* com.game79.aop.Book.*(..)) (3)execution(* *.*(..)) |
增强配置
<!-- 1 配置对象 --> <bean id="book" class="com.game79.aop.Book"></bean> <bean id="strongBook" class="com.game79.aop.StrongBook"></bean> <!-- 2 配置aop操作 --> <aop:config> <!-- 1.配置切入点 --> <aop:pointcut expression="execution(* com.game79.aop.Book.*(..))" id="pointcut1"/> <!-- 2.配置切面 把增强用到方法上面 --> <aop:aspect ref="strongBook"> <!-- 1.前置通知 配置增强类型 method:增强类里面使用哪个方法作为前置增强 pointcut-ref:增强用在哪个切入点上 --> <aop:before method="beforeAdvice" pointcut-ref="pointcut1"/>
<!--2.后置通知 --> <aop:after method="after1" pointcut-ref="pointcut1"/>
<!--3.环绕通知 --> <aop:around method="arround1" pointcut-ref="pointcut1"/> </aop:aspect> </aop:config> | |
最终执行结果:
|
log4j
1.通过log4j可以看到程序运行过程中更详细的信息。(哪些对象创建了,加载了哪些配置文件) (1) 经常使用log4j查看日志 (2) 复制log4j的jar包 |
AOP增强注解方式
1. 创建类
2.配置文件
|
Spring的jdbcTemplate操作(jdbc模板操作)
1.spring框架一站式框架 (1) 针对三层,每一层都有解决技术
(2)在dao层使用jdbcTemplate 2.spring对不同的 持久化技术都进行了封装
jdbcTemplate对jdbc进行封装 3..jdbcTemplate使用和jdbcUtils使用相似,都对数据库进行封装
|
增加
1. 导入jdbcTemplate相关jar包
导入驱动jar包
2.创建对象,设置数据库信息
3.创建jdbcTemplate对象,设置数据源
3. 调用jdbcTemplate对象里的方法实现操作
注意报错信息:
|
删除
@Test public void delete(){ //.创建对象,设置数据库信息 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/spring_day03?serverTimezone=GMT%2B8"); dataSource.setUsername("root"); dataSource.setPassword("root"); //.创建jdbcTemplate对象,设置数据源 JdbcTemplate jdbcTemplate =new JdbcTemplate(dataSource); //调用update方法实现删除 String sql="delete from user where username=?"; int rows=jdbcTemplate.update(sql,"lucy"); System.out.println(rows); } |
修改
@Test public void update(){ //.创建对象,设置数据库信息 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/spring_day03?serverTimezone=GMT%2B8"); dataSource.setUsername("root"); dataSource.setPassword("root"); //.创建jdbcTemplate对象,设置数据源 JdbcTemplate jdbcTemplate =new JdbcTemplate(dataSource); //调用update方法 String sql="update user set password=? where username=?"; int rows=jdbcTemplate.update(sql,"1314","lucy"); System.out.println(rows); }
|
查询
1. 使用jdbcTemplate实现查询操作,跟dbUtils相似,但也有不一样的地方
不同的返回结果,有不同的实现类,比如BeanHandler | ||||||||
| ||||||||
2. 查询具体实现 第一:查询返回某一个值
第二:查询返回对象
第三查询返回list集合
第二 查询返回对象
第一个参数:sql语句 第二个参数:RowMapper,是接口,类似于dbutils里的接口 第三个参数:可变参数
第三个 查询返回list集合
|
c3p0连接池
Spring配置连接池和dao使用jdbcTemplate
1. spring配置c3p0连接池 第一步:导入相关jar包
附:c3p0最原始写法:
配置文件中配置c3p0连接池
2. dao使用jdbcTemplate
最终注解的图解
添加add()方法,测试:
|
Spring的事务管理
事务概念
1. 什么是事务? 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。 2. 事务特性 (1)原子性:一组操作,要么都成功,一个失败则全部失败 (2)一致性:前后数据总量不变 (3)隔离性:多个事务同时操作同一记录,之间互不影响 (4)持久性:事务提交之后,数据库真实生效。 3. 不考虑隔离级别产生读问题
4. 解决读问题 (1)设置隔离级别 |
Spring事务管理api
1. spring事务管理分两种方式 第一种:编程式事务管理 第二种:声明式事务管理 (1)基于xml配置文件实现 (2)基于注解实现 2. spring事务管理的api介绍
(1)spring针对不同的dao层框架,提供接口不同的实现类
|
搭建转账环境
1. 创建数据库表,添加数据
2. 创建service和dao类完成注入关系
3. 产生的问题 (1) 如果小王少了1000之后,出现了异常,小马就不会多1000,钱就丢失了。 4. 解决方法 (1)添加事务解决,出现异常做回滚操作。
|
声明式事务管理(xml配置)
第一步:配置事务管理器
第二步:配置事务增强
第三步:配置切面
<!-- 第一步:配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入dataSource --> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 第二步:配置事务增强 --> <tx:advice id="txadvice" transaction-manager="transactionManager"> <!-- 做的什么事情 做事务操作 --> <tx:attributes> <!-- 设置进行事务操作的方法匹配规则 --> <tx:method name="account*" propagation="REQUIRED" /> <!-- <tx:method name="insert*" /> --> </tx:attributes> </tx:advice> <!-- 第三步 配置切面 --> <aop:config> <!-- 切入点 --> <aop:pointcut expression="execution(* com.game79.service.OrdersService.*(..))" id="pointcut01" /> <!-- 切面 --> <!-- 把哪个增强用在哪个切入点上 --> <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut01" /> </aop:config> |
注:看到上述配置,我提出一个疑问,就是在第二步中的 <tx:method name="account*" propagation="REQUIRED" /> 配置中已经制定在account方法上加事务操作(在其上加入增强),而第三步操作中,切入点 <aop:pointcut expression="execution(* com.game79.service.OrdersService.*(..))" id="pointcut01" /> <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut01" />
中表达式也将实际增强到具体方法上。难道不是指定重复了吗?
解答: 理解错误:第二步操作上,只是声明,并未增强。 <aop:pointcut expression="* com.game79.OrdersService.*.*(..)" id="pointcut01"/> 这里定义了切入点是:com.game79.OrdersService包下的所有类的全部方法。 tx:method name="account*" 这里声明的方法如果包含在切入点里则表示作为一个事务执行。
个人认为:事务操作都是从切入点开始的,可以把切入点看作是一个入口,即使是声明了account*这样的方法做事务操作,但是不符合切入点表达式的要求,则(拒绝入内)无法进行增强(若是事务操作,则事务不生效)。 |
声明式事务管理(注解)
第一步:配置事务管理器
第二步:配置事务注解
第三步:要使用事务的方法所在的类上添加注解
|
完整测试代码
1. OrdersDao类(注意包名不同)
2. OrdersService类
3. TestService类
4. 配置
|