什么是spring
- 是一个框架,核心技术是ioc,aop,实现解耦合。
- spring是一个容器,容器中存放的是java对象,需要做的是把对象放入到容器中。
怎么使用spring
- spring是一个容器,把项目中用到的对象放入到容器中。
- 让容器完成对象的创建,对象之间关系的管理(属性赋值)。
- 我们在程序中从容器中获取要使用的对象。
什么样的对象放入容器中
- dao类,service类,controller类,工具类。
- 使用xml配置文件,使用
<bean>
- 注解
- spring中的对象默认都是单例的,在容器中叫这个名称的对象只有一个。
不放入到spring容器中的对象
- 实体类对象,实体类数据来自数据库的
- servlet,listener,filter等
使用spring框架的步骤
- 加入依赖:spring-context
- 创建类:接口、实现类,没有接口的类
- 创建spring的配置文件,使用
<bean>
声明对象 - 我们使用容器中的对象,通过ApplicationContext接口和他的实现类ClassPathXmlApplicationContext的方法getBean()
核心技术
ioc:控制反转
- 理论、思想、概念:指导开发人员在容器中,代码之外管理对象,给属性赋值,管理依赖。
- ioc技术实现使用的di(依赖注入):开发人员在项目中只需要提供对象的名称,对象的创建、查找、赋值都由容器实现。
- spring使用的di的技术,底层使用的是反射机制。
- di给属性赋值
- set注入:spring调用类的set方法实现属性赋值。
- 简单类型的set注入
<property name="属性名" value="属性值"/>
- 引用类型的set注入
<property name="属性名" ref="bean的id"/>
- 构造注入:spring调用有参数构造方法。
<constructor-ags>
的name属性,name表示构造方法的形参名。<constructor-ags>
的index属性,表示构造方法形参的位置,从0开始。
- 自动注入: 由spring根据某些规则,给引用类型完成赋值,常用的有byName,byType
-
byName: 按名称注入,java类中引用类型的属性名和spring容器中的bean的id一样,这样的bean赋值给引用类型。
-
byType:按类型注入,java类中引用类型的数据类型和spring容器中bean的class是同源关系的,这样的bean能够赋值给引用类型。
-
常用注解
- @Component,创建对象
- @Repository,创建dao对象,用来访问数据库
- @Service,创建service对象,处理业务逻辑,可以有事务功能
- @Controller,创建控制器对象,接收请求,显示处理结果
- @Value,简单类型的属性赋值
- @Autowired,spring框架中引用类型的赋值注解,支持byName,byType,默认是byType
- @Resource,jdk中的注解,使用自动注入给引用类型赋值,支持byName,byType,默认是byName
- 注解的使用步骤
- 加入依赖:spring-context,间接加入spring-aop
- 在类中加入注解
- 在spring的配置文件中,加入组件扫描器的标签
<context:component-scan base-package="包名">
- ioc能实现解耦合
ioc能实现业务对象之间的解耦合,例如service和dao对象之间的解耦合。
aop面向切面编程
- 底层是动态代理
- jdk动态代理
- 使用jdk反射包中的类实现创建代理对象的功能。
- 要求:目标类必须实现接口。
- cglib动态代理
-
使用第三方的工具库,实现代理对象的创建。
-
要求:目标类必须能够继承,不能是final
-
原理:就是继承,子类就是代理。
-
代理的使用方式
- 如果目标类有接口,框架使用jdk动态代理。
- 如果目标类没有接口,默认使用的cglib代替代理。
- 有接口也可以强制使用cglib动态代理。
- aop:看作是动态代理的规范化,把实现动态代理的步骤进行了规范和定义
- aop作用
- 在目标类不修改源代码的情况下,增加功能。
- 减少重复代码。
- 专注业务功能的实现。
- 解耦合:业务功能和日志、事务这些非业务功能的耦合。
- 什么时候考虑使用aop技术
- 当需要给一个项目中存在的类修改功能,但是原有类的功能不完善,而且还没有源代码,使用aop增加功能。
- 要给项目中的多个类,增加一个相同的功能,使用aop。
- 给业务方法增加事务、日志输出。
- aop的实现框架
- spring实现了aop,实现方式是接口。
- aspectj框架。
- 使用注解可以实现aop的功能。
- 使用xml配置文件中的标签实现aop功能。
- aop中概念
- aspect:切面,表示给业务方法增加功能,一般日志输出,事务,权限检查等是切面。
- pointCut:切入点,是一个或多个JoinPoint的集合,表示切面功能执行的位置。
- advice:通知,也叫增强,表示切面执行的时间,在方法前,方法后等。
- aspectj框架的使用
- 表示切面的执行时间,使用的通知注解。
- @Before:前置通知,在目标方法之前先执行切面的功能。
- @AfterReturning:后置通知,在目标方法之后执行的,能够获取到目标方法的返回值。
- @Around:环绕通知,在目标方法前和后都能增强功能,控制目标方法的访问,修改返回值。
- @AfterThrowing:异常通知,在目标方法抛出异常后执行的通知。
- @After:最终通知,总是会被执行的代码。
- @PointCut:定义和管理切入点的辅助注解。
- 表示切面位置的切入点表达式:execution(访问修饰符 返回值 包名。类名。方法名称(方法的参数)异常)
spring整合mybatis
- 整合的想法:使用spring的ioc核心技术,把mybatis框架中使用的对象交给spring统一创建和管理。spring是容器,存放项目中要使用的各种对象,例如Service对象,Dao对象,工具类对象等。
- 交给spring的mybatis对象
- 数据源DataSource,使用阿里公司的Druid连接池。
- SqlSessionFactory对象,使用的SqlSessionFactoryBean在内部创建的SqlSessionFactory
- Dao代理对象,使用的MapperScannerConfigure,在这个类的内部,调用getMapper(),创建接口的Dao对象。
spring的事务处理
- 什么是事务:事务是指一组Sql语句的集合,这些sql语句要么都执行成功,要么都不执行。这些sql语句是一致,作为一个整体执行。
- 原子性:一个事务要么都执行成功提交,要么全部失败回滚,不能只执行其中一部分,这就是事务的原子性。
- 一致性:事务的执行不能破坏数据的完整性和一致性;一个事务在执行之前和执行之后,数据库必须处于一致性状态。
- 隔离性:发生在并发的环境中,指一个事务的执行过程不能被其他事务所干扰。
- 读未提交:出现脏读、不可重复读、幻读。
- 读已提交:可解决脏读,无法解决不可重复读、幻读,Oracle默认的隔离级别。
- 可重复读:可解决脏读、不可重复读,无法解决幻读。mysql InnoDB存储引擎的默认隔离级别。
- 串行化:能够解决脏读、不可重复读、幻读、隔离级别最高,但是并发性能最低。
- 持久性:一个事务如果提交成功,那么它对数据状态的变更会永久性的保存到数据库中。
- 什么时候需要事务
- 涉及多个表、多个sql语句的增删改。
- 在java开发中,事务是放在service类中的业务方法上的。
- 如何访问数据、处理事务
- jdbc
- Connection conn
- conn.commit
- conn.rollback
- mybatis
- SqlSession.commit
- SqlSession.rollback
- hibernate
- Session.commit
- Session.rollback
- 不同的事务处理方式带来的问题
- 不同的数据库访问技术,在处理事务上会有所不同。需要了解不同数据库访问技术处理事务的原理。
- 掌握多种数据库中,事务的处理逻辑,你需要什么时候提交、什么时候回滚,以及相应的方法。
- 怎么解决:spring提供一种统一的模型,能够使用统一的步骤来完成多种数据库访问技术的事务处理。
- 如何做
- spring处理事务的模型和步骤都是固定的,把事务的使用信息提供给spring就可以了。
- 声明相应数据库访问技术的实现类,在spring配置文件中声明该实现类的bean。
- 声明需要的事务方法和相应的参数。
- 提交事务,回滚事务的时机。
- Spring框架中提供的事务处理方案
- 适合中小项目使用的:注解方案。Spring使用aop给方法增加事务功能,使用注解:@Transactional,放在public方法上边,表示当前方法具有事务。可以给注解赋值,表示隔离级别,传播行为等。
- propagation:表示事务的传播行为,默认为PROPAGATION_REQUIRED
- isolation:表示事务的隔离级别
- rollback:指定回滚的异常类
- timeout:超时时限,默认没有时限
- readOnly:用于设置对数据库的操作是否为只读,默认为false
- 适合大型项目,有很多的类,很多的方法需要配置事务。使用aspectJ框架功能,在spring配置文件中声明类,方法需要的事务,这种方式让业务方法和事务完全隔离。