一、Spring
- 为什么要学Spring?
- Spring在学什么?
- Spring该怎么学?
1、初识Spring
a.认识spring
b.spring发展史
2、Spring Framework系统架构
a.Spring系统架构图
系统架构图讲究上层依赖于下层;
第一核心大块
1、Core Container表明Spring是一个用来管理对象的技术,即Core Container中装的就是对象;
第二核心大块
1、AOP需要依赖于核心容器的执行(面向切面编程和面向对象编程一样,都属于一种编程思想,换句话说,它就是教你程序该怎么做,即又是一种设计型的概念,而Spring对这种概念进行了落地),具体的AOP技术是:它可以在不惊动你原始程序的基础上,给这个程序增强功能;
2、Spring对AOP进行了实现,而Aspects也是对AOP进行了实现,而Aspects对AOP的实现做得更加完美,所以Spring大胆将其收入其整个技术栈中,表明它承认Aspects的优秀,建议大家使用其技术,因此在后续开发过程中,程序员不仅需要导入AOP的坐标,还要导入Aspects的坐标;
第三核心大块
1、Data Access是在做与数据层相关的技术开发;
2、Data Integration表示Spring内部不仅提供了自主的访问数据层的技术,同时它还支持你用Spring技术与其他技术整合使用,而这个整合表示它包容其他技术,比如Mybatis可以和Spring整合在一起使用;
3、在整个数据大模块中的Transactions事务,Spring在事务这方面做了非常大的突破,给我们提供了一种开发起来效率非常高的事务控制方案,这是之后研究学习的重点;
第四核心大块
1、业务层的Web开发,Spring也可以进行Web开发,后续SpringMVC会涉及到;
2、而测试层相对来说比较简单,构不成独立的模块;
b.Spring学习路线
3、核心概念
a.概念的引入
概念的引入是为了解决一些问题,因为现在的代码存在耦合度高的问题(假如现在已经上线了一个项目,项目中的业务层实现了数据层的某个接口,假如你现在要换一套数据层的实现,则业务层的代码需要变动,究其根本原因就是代码的耦合度高);
b.解决方案(利用IOC控制反转)
c.Bean(本质上还是一个对象)
IOC容器管它造出来的对象称为Bean;
Spring管理的思想为:我来一个IOC容器,你将造对象的活交给IOC来干,然后造出来的对象叫做Bean,你要使用的话,我直接给你使用就可以;
d.DI(依赖注入)与最终目标
问题:现在我们程序如果运行的话,假如说需要使用service对象,你是不是IOC容器直接给你对象就可以使用了?
1、答案是否定的,因为你的service里面运行需要依赖dao对象才能运行,你光给我一个service对象是不足以让我成功运行的,所以你运行还是会报错;
2、由于我们需要使用的两个对象都在IOC容器里面放着,所以IOC容器也帮你把依赖的活给干了,即它帮你把service和dao之间的依赖关系给你绑定上了,因此你现在所需要的dao对象,它直接给到你就可以顺利进行了;
因此,依赖注入的含义就是IOC容器将有依赖关系的两个bean帮你自动给绑定上,方便你后续的使用,而这个绑定的过程就叫做依赖注入,以达到你现在再拿service对象的时候,你想使用里面的dao,就直接有对象了,程序既能成功运行,同时也解耦;
4、IOC入门案例
a.思路分析
b.原代码分析
c.使用IOC
d.具体步骤
e.存在的问题
案例完成后会发现其实在业务层还是存在着new什么什么,也就是说我们充分解耦的效果还没做到,那么这个时候就要用到DI了;
5、DI入门案例
根据前面IOC案例原有的代码进行修改,首先是Service接口的实现类
a.去除new形式的对象并提供进入Service的方法
b.配置Service和Dao的关系
c.剔除多余的导包
d.具体步骤
6、bean详细内容
a.bean基本配置
b.bean别名配置
c.bean作用范围配置
它实际上是控制我们bean创建的实例的数量的;
问题:为什么bean默认为单例?
对于spring来说,它帮我们管理的bean是要放到它的容器中的;我们假定一个场景,如果它造出来的bean不是非单例的,那么这个bean的数量会是无穷无尽的,即每用一次就要造一个,因此spring它并不是帮我们管理这一类bean的(非单例),毕竟这对spring的容器来说也有很大的压力,所以spring其实帮我们管的bean都是单例的;
问题:spring帮我们管理的bean都是单例的,会对我们的业务造成伤害吗?
答案是否定的。因为你造一个对象,执行完一个方法,下一次你又需要造一个对象,再执行另一个方法,那我这两个对象用同一个也无伤大雅呀,所以spring在帮我们管理对象的时候,其实就是管理那些你可以复用的对象,这样它的效率才会更高一些,因此它干脆就简单点给你造的bean就是单例的;
d.bean的实例化
①bean是如何创建出来的
bean本质上就是对象,创建bean一般使用构造方法完成(spring创建bean的时候,创建的是无参的构造方法),也就是采用实例化的方式创建出来的;
②实例化的三种方式
- 实例化的三种方式--构造方法(常用)
- 实例化的三种方式--静态工厂(了解)
- 实例化的三种方式--实例工厂与FactoryBean(了解)
实例工厂:
FactoryBean:
③总结
e.bean的生命周期及控制
7、依赖注入方式
a.使用setter注入——引用类型
b.使用setter注入——简单类型
c.构造器注入——引用类型(了解)
d.构造器注入——简单类型(了解)
e.构造器注入——参数适配(了解)
f.依赖注入方式选择
分析:
强制依赖简单来说就是你这个bean运行必须要的东西用构造器注入,因为构造器一旦指定了,那么你那个参数就必须给,如果你忘了给这个对象,你都造不成配置文件(会报错),所以说强制依赖使用构造器注入;
但是使用setter注入的时候就不是这样了,因为setter注入这个set方法的执行,你可以执行,也可以不执行,所以setter你不给他注入的时候,就会出现对应的对象成为空的这种现象;重点!一般自己开发的模块推荐使用setter注入,因为比较灵活!
结论:
如果你要用别人的类,别人提供了setter和构造器了,那就用setter好了;
假如他只提供了构造器,那没得选,只能用构造器;如果是自己写的话,那就别给自己添麻烦,全部写上setter注入就好了,灵活性高!!!!
8、依赖自动装配
使用细节:
- 第一、首先自动装配用于引用类型的依赖注入,它不能对简单类型进行操作,因为如果简单类型中注入一个数字1,你根本想象不到这个数字1的bean该怎么写(能写,但没必要,因为如果1写了,那么2要不要写?3呢?),所以它只对引用类型做依赖注入;
- 第二、如果使用按类型的话,要求容器中相同类型的bean唯一;
- 第三、如果按名称装配的话,要求我们容器中指定名称的bean必须存在,如果不存在的话,会报错,但是这种形式并不好,会出现一个很强的耦合(就是你的配置文件要和你后面的程序要耦合);
- 第四、手写的内容优先与自动装配的内容,也就是说这个时候自动装配会失效;
总结:
1.自动装配就是根据类型或者根据名称,IOC容器他根据依赖资源自动查找并装载到bean中的过程;
2.自动装配的类型有四种,主要推荐使用按类型自动装配;
总体上还存在一个小疑问,就是引用类型可以注入,基本数据类型也可以注入,但是集合怎么办(因为注入集合的话,不是注入集合的壳,而是注入其内容)?
9、集合注入
a.数组
b.List
c.Set
d.Map
e.Properties
10、第三方资源配置管理
a.管理配置druid
b.学会管理配置陌生的内容(c3p0)
11、加载properties文件
a.加载properties配置文件信息
b.开启命名空间的方式
c.加载properties文件要注意的细节
12、容器
a.创建容器
b.获取bean
c.容器类层次结构图
d.BeanFactory初始化
BeanFactory是所有容器的顶层接口!!!
13、核心容器总结
a.容器相关
b.bean相关
c.依赖注入相关
14、注解开发定义bean
a.注解开发定义bean(Spring2.0开始有)
b.纯注解开发(Spring3.0推出的)
15、bean管理
a.bean作用范围
b.bean生命周期
16、注解开发依赖注入
a.自动装配
读取内部文件内容
b.读取properties文件
读取外部可变文件内容
17、注解开发管理第三方bean
a.第三方bean管理(全放在spring的配置类内)
b.第三方bean依赖注入(放在各自独立的配置内)
c.注解开发实现为第三方bean注入资源
简单类型:成员变量
引用类型:方法形参
18、注解开发总结
a.XML配置与注解配置比较
19、Spring整合Mybatis
a.SqlSessionFactory是怎么来的呢?
- 我们所有的配置都是围绕着这个对象进行的,在它的核心配置中,首先加载数据库对应的外部配置信息(初始化属性数据),这个和Mybatis没有什么直接的关系,相当于这个数据你不在这里写,也可以在别的地方写,因此可以忽略掉;
- 第二部分(初始化类型别名),我们的mybatis操作完以后,得到的数据封装成什么样,也就是那个tab lies那个别名;
- 第三部分(初始化dataSource),是用来连接哪个数据库配它的dataSource,也就是说你的SqlSessionFactory要是都不知道你操作哪个数据库,你是根本无法进行连接的,所以说,第三部分内容一定是为我们的SqlSessionFactory服务的(其中事务管理用的jdbc事务,总体上还是为这个东西服务的,因为你的SqlSessionFactory最终造的SqlSession是操作数据库的,所以第三部分全都是为他服务的);
- 最后一部分(初始化映射配置),是你把你的SqlSessionFactory造完以后,再去根据不同的配置加载以后,可以得到不同的mapper,然后去操作不同的库表,也就是说我们前面的内容实际上是做大的连接管理,而最后这一部分是我们的业务操作;换句话说就是即使业务操作不存在,你的Mybatis也应该是成立的,所以最后一部分是伴随着你的业务在进行变化的,核心对象实际上是上面的部分,这部分信息是给我们的SqlSessionFactory来初始化的;
- 结论:Mybtis应该管的内容是SqlSessionFactory对象!!!
b.整合Mybatis
20、整合Junit
21、AOP简介
a.AOP核心概念
- AOP是一个大的概念,不光Spring有AOP还有其他种类的AOP;
- 切入点范围小,连接点范围大,切入点一定在连接点中;
b.AOP作用
面向对象和面向切面编程都是一种编程思想,换句话说就是指导你做程序的,它是一种编程的范式,面向对象编程指导你做类做对象,以及继承封装等内容;而面向切面编程只在不惊动原始设计的基础上为其进行功能的增强;
22、AOP入门案例
23、AOP工作流程
a.AOP实质上的工作流程
b.AOP核心概念
SpringAOP本质为代理模式
24、AOP切入点表达式
25、AOP通知类型
a.@Before
b.@After
c.@Around
分析:
- 第一条,简单过一遍就行;
- 第二条,ProceedingJoinPoint是对原始方法的调用,如果你没有执行对原始方法的调用,就会产生一种对原始操作进行隔离的效果,也就是说你可以进行权限校验,比如说你现在要想运行我的方法你必须得是经理的权限,我不想让你调原始操作的话,用around就可以实现;
- 第三和第四条,对原始方法的调用的那个返回值,你可以不接收,也就是将通知的方法设置为void,是可以这么操作的,但是一般来说不主张这么设置,通常的做法是设置成Object类型;
- 最后一条,因为你无法预知原始方法会不会抛异常,所以说这里会强制让你抛一个throw的对象,避免出现问题,如果不抛异常的话,相当于出现问题以后,你将问题给隐藏起来了,所以在这要求你要么进行异常处理,要么抛出去,建议直接使用抛异常。