Tips:本笔记主要信息来源为传智播客的《60集精通java教程Spring框架开发》,笔记内容为:学习资料 + 个人补充;如有内容或排版方面的错误,欢迎纠正~
内容分布
- spring概念和ioc入门(ioc操作xml配置文件)
- spring的ioc操作(注解)和aop概念
- jdbcTemplate和spring管理事务
- ssh框架整合[开发]1
Spring概念与IOC入门
Spring概念
Spring是开源的轻量级框架
Spring的核心包括两个部分
-aop:面向切面编程,扩展功能不是修改源代码实现
-ioc:控制反转
- 比如有一个类,在类里面有方法(不是静态的方法),调用类里面的方法,创建类的对象,使用对象调用方法,创建类对象的过程,需要new出来对象。在这里,对象的创建不是通过new方式实现,而是交给spring配置创建类对象spring是一站式框架
spring在javaee三层结构中,每一层都提供不同的解决技术
- web层:springMVC
- service层:spring的ioc
- dao层:spring的jdbcTemplateSpring的版本
-hibernate:5.x
-Spring4.x(这里学习的版本)
Spring的ioc操作
- 把对象的创建交给spring进行管理
- ioc操作两部分:
1)ioc的配置文件方式
2)ioc的注解方式
IOC底层原理
ioc底层原理使用技术
(1)xml配置文件
(2)dom4j解决xml
(3)工厂设计模式
(4)反射画图分析ioc实现原理
IOC和DI区别
- IOC: 控制反转,把对象创建交给spring进行配置
- DI: 依赖注入,向类里面的属性中设置值
- 关系:依赖注入不能单独存在,需要在ioc基础之上完成操作
Spring整合web项目原理
Spring整合web项目原理
加载spring核心配置文件
ApplicationContext context = new ClasssPathXmlApplicationContext("xml路径")
//new 对象;的方法,功能可以实现,效率很低实现思想:把加载配置文件和创建对象过程,在服务器启动时候完成
实现原理
(1)ServletContext对象
(2)监听器
(3)具体使用:- 在服务器启动时候,为每个项目创建一个ServletContext对象
- 在ServletContext对象创建时候,使用监听器可以具体到ServletContext对象在什么时候创建
- 使用监听器监听到ServletContext对象创建时候,
- 加载spring配置文件,把配置文件配置对象创建
- 把创建出来的对象放到ServletContext域对象里面(setAttribute方法)
- 获取对象时候,到ServletContext域得到(getAttribute方法)
Spring整合web项目演示
导包
- struts2相关jar包:
- Spring相关jar包
- Spring-web整合包:
Spring-web-3.0.7.jar(myeclipse2015可支持的最高版本)
- struts2相关jar包:
代码实现之准备部分
1 | //---UserService.java--- |
- 代码实现之Spring与struts2配置文件
1 | <!------ applicationContext.xml ------> |
- 代码实现之spring与struts2的整合
1 | //------web.xml------ |
- 验证
通过访问 localhost:8080\项目名\UserAction.action 验证
Spring的bean管理(xml)
bean实例化的方式
在Spring中通过配置文件创建对象
bean实例化的三种方式
1.使用类的无参构造方法创建(重点)
1
2<!-- 若类中没有无参构造方法,会出现异常。 -->
<bean id=“user” class=“cn.itcast.ioc.User”></bean>2.使用静态工厂创建
1 | //创建静态的方法,返回类对象 |
3.使用实例工厂创建
1 | // Bean3Factory.java |
Bean标签常用属性
- id属性:起名称,id属性值名称任意命名
- id属性值,不能包含特殊符号
- 根据id值得到配置对象
- class属性:创建对象所在类的全路径
name属性:功能和id属性一样的,id属性值不能包含特殊符号,但是在name属性值里面可以包含特殊符号
scope属性
- singleton:默认值,单例
- prototype:多例
- request:创建对象把对象放到request域里面
- session:创建对象把对象放到session域里面
- globalSession:创建对象把对象放到globalSession里面
属性注入
属性注入介绍
创建对象时候,向类里面属性里面设置值
属性注入的方式的三种方式
- 使用set方法注入(重点)
- 使用有参数构造注入
使用接口注入
! 在spring框架里面,支持前两种方式1
2
3
4
5
6
7
8
9
10
11
12
13//使用有参数构造注入属性
<!-- 第一种:构造方法的方式 -->
<bean id="car" class="cn.itcast.spring.demo4.Car">
<constructor-arg name="name" value=" 保 时 捷 "/>
<constructor-arg name="price" value="1000000"/> </bean>
//------------------------------------------
//使用set方法注入属性(重点)
<!-- 第二种:set方法的方式 -->
<bean id="car2" class="cn.itcast.spring.demo4.Car2">
<property name="name" value=" 奇 瑞 QQ"/>
<property name="price" value="40000"/>
</bean>
注入对象类型属性(重点)
- 具体实现过程
(1)在service里面把dao作为类型属性
(2)生成dao类型属性的set方法
(3)配置文件中注入关系
相关代码:
1 | //------------------------------------ |
P名称空间注入(Spring2.x 版本后提供的方式)
1 | <!--第一步:引入p名称空间 --> |
SpEL 的方式的属性注入(Spring3.x 版本后提供的方式)
1 | <!--SpEL:Spring Expression Language. |
注入复杂类型属性
1 | <!-- Spring 的复杂类型的注入===================== --> |
Spring的Bean管理(注解)
注解介绍:
- 代码里面特殊标记,使用注解可以完成功能
- 注解写法 @注解名称(属性名称=属性值)
- 注解使用在类上面,方法上面 和 属性上面
Spring注解开发准备
导入jar包
基本的jar包
aop的jar包:Spring-aop-4.3.4.RELEASE.jar
创建类,创建方法
1
2
3
4
5
6
7
8
9
10public interface UserDao {
public void sayHello();
}
public class UserDaoImpl implements UserDao {
public void sayHello() {
System.out.println("Hello Spring...");
}
}创建spring配置文件,引入约束
(1)第一天做ioc基本功能,引入约束beans
(2)做spring的ioc注解开发,引入新的约束
- 开启注解扫描
1
2<!-- Spring 的注解开发:组件扫描(类上注解: 可以直接使用属性注入的注解) -->
<context:component-scan base-package="com.itheima.spring.demo1"/>
注解创建对象
在创建对象的类上面使用注解实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14//通过注解注册Bean
"userDao") (value=
public class UserDaoImpl implements UserDao {
public void sayHello() {
System.out.println("Hello Spring Annotation...");
}
}
//测试方法中获取bean对象
public void demo2() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao"); userDao.sayHello();
}创建对象有四个注解(目前这四个注解功能是一样的,都创建对象)
(1)@Component
(2)@Controller:web层
(3)@Service:业务层
(4)@Repository:持久层
! 指定创建对象单实例还是多实例的方法
1 | //注解的方式 |
注解注入属性:(使用注解注入的方式,可以不用提供 set 方法.)
- @Value :用于注入普通类型.
- @Autowired :自动装配: * 默认按类型进行装配.
- 按名称注入:
- @Qualifier:强制使用名称注入.
- @Resource相当于:
- @Autowired和@Qualifier一起使用.
示例:
1 | //创建dao和service对象 |
配置文件和注解混合使用
1 | //使用配置文件方式实现创建对象操作 |
AOP
AOP相关概念
- AOP:面向切面(方面)编程,在不修改源码的情况下扩展功能
- AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
- AOP底层使用动态代理实现
- 第一种情况,有接口情况,(JDK 的动态代理 )使用动态代理创建接口实现类代理对象
- 第二种情况,没有接口情况,( Cglib 的动态代理)使用动态代理创建类的子类代理对象
AOP原理
1 | //Cglib 动态代理增强一个类中的方法: |
Spring 的基于 AspectJ 的 AOP 开发
在spring里面进行aop操作,使用aspectj实现
(1)aspectj不是spring一部分,和spring一起使用进行aop操作
(2)Spring2.0以后新增了对AspectJ支持使用aspectj实现aop有两种方式
(1)基于aspectj的xml配置
(2)基于aspectj的注解方式
AOP操作术语
- Joinpoint(连接点): 类里面可以被增强的方法,这些方法称为连接点
- Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.
- Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.
通知分为:前置通知;后置通知;异常通知;最终通知;环绕通知(切面要完成的功能) - Aspect(切面): 是切入点和通知(引介)的结合
- Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.
- Target(目标对象):代理的目标对象(要增强的类)
- Weaving(织入):是把增强应用到目标的过程.把advice 应用到 target的过程
- Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
切入点表达式
切入点,即实际增强的方法
- 表达式格式为
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
(1)execution(* cn.itcast.aop.Book.add(..))
(2)execution(* cn.itcast.aop.Book.*(..))
(3)execution(* *.*(..))
(4) 匹配所有save开头的方法 execution(* save*(..))
Spring 使用 AspectJ 进行 AOP 的开发:XML 的方式(*)
导包
除了导入基本的jar包之外,还需要导入aop相关的jar包创建配置文件,导入aop约束
1
2
3
4
5
6
7<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>编写切面类
1
2
3
4
5
6
7
8
9
10public class MyAspectXml {
// 定义前置增强方法
public void before(){
System.out.println("前置增强===========");
}
// 定义后置增强方法
public void methodName(){
System.out.println("后置增强===========");
}
}配置切入点
1
2
3
4
5
6
7
8
9
10
11
12<!-- 配置切面类 -->
<bean id="myAspectXml" class="cn.itcast.spring.demo3.MyAspectXml"></bean>
<!-- 进行 aop的配置 -->
<aop:config>
<!-- 配置切入点表达式:哪些类的哪些方法需要进行增强 -->
<aop:pointcut expression="execution(* cn.itcast.spring.demo3.OrderDao.*(..))" id="pointcut1"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<aop:before method="before" pointcut-ref="pointcut1"/>
<aop:after method="methodName" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>编写测试程序
1
2
3
4
5
6
7
8
public void testOrderDao(){
//获取applicationContext
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean2.xml");
//使用接口类取得Bean
OrderDao orderDao = (OrderDao)ctx.getBean("orderDao");
orderDao.save();
}
Spring 使用 AspectJ 进行 AOP 的开发:注解的方式
- 创建对象
1 | <!-- 创建对象 --> |
在配置文件中开启aop操作
1
2<!-- 开启aop操作 -->
<aop:aspect-autoproxy></aop:aspectj-autoproxy>在增强类上使用注解
1
2
3
4
5
6
7
8
public class MyBook{
//在方法上使用注解完成增强配置
"execution(* cn.itcast.aop.Book.*(..))") (value=
public void Before1(){
System.out.println("before...");
}
}
Spring的jdbcTemplate操作
jdbcTemplate引入
spring框架一站式框架
(1)针对javaee三层,每一层都有解决技术
(2)在dao层,使用 jdbcTemplatespring对不同的持久化层技术都进行封装
jdbcTemplate使用和dbutils使用很相似,都数据库进行crud操作
用jdbcTemplate实现增删改
- 导入jdbcTemplate使用的jar包
- spring-jdbc-4.2.4.RELEASE.jar
- spring-tx-4.2.4.RELEASE.jar
- jdbc-connector-xx.jar(依赖包)
创建对象,设置数据库信息
创建jdbcTemplate对象,设置数据源
调用jdbcTemplate对象里面的方法实现操作
- int update(String sql,Object… args);
1 |
|
用jdbcTemplate实现查询操作
回顾:jdbc上的查询操作
1 | Connection conn = null; |
jdbcTemplate上的查询操作
- 查询的种类
- 返回结果为一个值
使用方法:T queryForObject(String sql,Class<t> re quiredType);
//参数1:sql语句;参数2:返回值类型.class - 返回结果为一个对象
使用方法:T queryForObject(String sqlRowMapper<T> rowMapper,Object... args);
//参数1:sql语句;参数2:RowMapper接口(要自己写);参数3:可变参数 - 返回结果为List集合
使用方法:List<T> query(String sqlRowMapper<T> rowMapper,Object... args);
//参数1:sql语句;参数2:RowMapper接口(要自己写);参数3:可变参数
- 返回结果为一个值
实现过程:
1 | //创建dataSource(略) |
Spring配置连接池和dao使用jdbcTemplate
Spring配置c3p0连接池
导包
c3p0-0.9.2.1.jar
mchange-commons-java-0.2.3.4.jar在Spring配置文件中配置连接池
1 | <!-- 配置c3p0连接池--> |
在dao中使用jdbcTemplate
配置xml文件后就可以直接使用连接池
1 | //---- 创建service和dao,配置service和dao对象---- |
事务操作
回顾:事务
什么是事务?
事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败.事务特性:
- 原子性 :强调事务的不可分割.
- 一致性 :事务的执行的前后数据的完整性保持一致.
- 隔离性 :一个事务执行的过程中,不应该受到其他事务的干扰
- 持久性 :事务一旦结束,数据就持久到数据库
如果不考虑隔离性引发安全性问题:
- 脏读 :一个事务读到了另一个事务的未提交的数据
- 不可重复读 :一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致.
- 虚读 :一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果不一致.
解决读问题:设置事务隔离级别
- 未提交读 :脏读,不可重复读,虚读都有可能发生
- 已提交读 :避免脏读。但是不可重复读和虚读有可能发生
- 可重复读 :避免脏读和不可重复读.但是虚读有可能发生.
- 串行化的 :避免以上所有读问题.
Spring事务管理api
- spring事务管理两种方式
- 第一种 编程式事务管理(不用)
- 第二种 声明式事务管理
(1) 基于xml配置文件实现
(2) 基于注解实现
相关代码
1 | //------基于配置文件实现------ |
1 | //------注解方式实现事务------ |
Tips
- Spring分模块开发(将配置文件中的一部分分出去)
1
2<!-- 在主配置文件中,引入其他配置文件 -->
<import resource="classpath:user.xml" />
在最后
Spring的基本内容已结束,随后还有ssh的整合部分,暂时不会去写,因为hibernate还没学习。谢谢你们的阅读
To be continue…
1. qqqqq ↩