特征
- 简化开发:降低企业级开发的复杂性。
- 框架整合:高效整合其他技术,提高企业级应用开发与运行效率。
介绍
Spring发展到今天已经形成了一种生态圈,Spring提供了若干个项目,每个项目用于完成特定的功能,俗称Spring全家桶。全家桶里包含了如Spring Framework(spring框架),SpringBoot等。
Spring Framework
介绍
是Spring生态圈中最基础的项目,是其他项目的根基。(因为spring全家桶太多了所以我们平常说的spring其实是Spring Framework)
系统架构
核心容器
IOC思想(控制反转)
在使用对象的时候不用主动new对象了,转为由外部提供对象。此过程中对象的创建控制权由程序转移到外部,俗称控制反转。
Spring技术对IOC思想进行了实现。
- Spring提供了一个容器,称为IOC容器,用来充当IOC思想中的"外部"。
- IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IOC容器中统称为Bean(IOC容器创建的bean默认是单例的)。
DI(依赖注入)
在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入。
(就是这里ioc管理了service对象和dao对象,他只是把对象创建出来让其他地方进行使用,至于如何使用就需要通过绑定依赖关系进行使用)
最终目的
充分解耦。
代码使用
这里用一个service对象和一个dao对象演示
1.先导spring的maven坐标
2.创建配置文件
3.创建bean
4.获取IOC容器(其他地方想调用IOC容器里的对象时)
5. 获取bean
然后就可以用了。
Bean是如何创建对象
构造方法
默认bean创建的对象是通过对象的无参构造方法来实现的。
如果想使用有参构造方法来创建对象可以看下面的---Bean依赖注入方式---构造器注入
下面的其他方法是对bean创建对象的扩展。
静态工厂(了解就行)
- 使用工厂创建一个impl对象。(不是工厂对象)
使用工厂创建对象可以在工厂里做点其他事,比如配置一些参数之类的。
实例工厂(了解就行)
因为调用实例方法需要先创建工厂对象,所以要先创工厂的bean。
但是这种方式每回都要多创建一个bean对象,很繁琐,所以衍生出了下面这一种方式。
FactoryBean
只用写这个FactoryBean的Bean对象就行
Bean依赖注入方式
setter注入
引用类型(bean对象之类的)
简单类型(基础数据类型与string)
构造器注入
引用类型(bean对象之类的)
简单类型(基础数据类型与string)
Bean依赖自动装配
IOC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
想要使用自动装配,setter方法还是要有。
按类型(常用)
这里只能有一个bookDao类型的bean,如果有两个或多个他就报错了。
如果有多个那就要用按名称方法了
按名称
注意
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作。
- 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效。
集合注入
数组
list集合
set集合
map集合
properties
Spring加载properties文件
比如这里有一个jdbc的配置文件,我们需要去加载使用它。
先在xml配置文件里加几行,用来开启context命名空间
使用context空间加载properties文件
如果有多个文件都要加载可以用*代替
classpath可加可不加,但是加上比较标准,所以最好都加上。
然后可以通过占位符的方式往bean里填充需要的数据
Bean相关属性总结
注解开发
上面的太麻烦了,使用注解进行简化。
创建Bean
首先,想把当前类当成bean可以使用@Component注解
想使用这些bean注解需要在配置文件里配置扫描路径,让配置文件知道去哪找到这些注解定义的bean。
有个更简单的方法可以不用配置文件了,改用java类。
这里创建一个java类,配置扫描路径后会扫描当前路径下的@Component及其衍生注解定义的bean。
改用java类后通过代码获得bean时也有改动
依赖注入
使用@Autowired注解自动装配。
这个注解是按类型装配的。
使用这个注解可以不用写set方法了。
如果有多个相同类型的bean,可以使用@Qualifier注解按名称注入。
注意:
自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法。
可以通过@Value注解向简单类型注入参数
这里看着感觉会有点多此一举了,但是使用这个注解可以通过配置文件获取值。
先在配置类上加载配置文件
然后直接使用占位符操作
注解管理第三方Bean
因为无法往第三方依赖里加注解,所以@ComponentScan注解就没用了,这时要用其他方法。
如果定义这个bean需要其他bean当参数,可以直接用
spring会自动装配进去,前提是这个参数也要是个bean。
AOP(面向切面编程)
作用
在不惊动原始设计的基础上为其进行功能增强。
核心概念
使用
导包:
找到要被加强的方法。(基础方法)
定义一个加强方法(用这个方法加强基础方法的功能)
定义切入点(这个切入点下面的切入点表达式会讲)
表示要在BookDao下的update方法进行加强
定义切入位置(下面的通知类型会讲)
表示在pt()指定的方法执行前要执行的加强逻辑。
接下来把注解加上。
需要在配置类上加个注解,表示开启注解开发aop。
工作流程
1.spring容器启动
2.读取所有切入点(用哪个读取哪个)
3.初始化bean(不是aop的bean,而是正常普通对象),判定bean对应的类中的方法是否匹配到任意切入点。
- 匹配失败,创建对象
- 匹配成功,创建原始对象(目标对象)的代理对象
4.获取bean执行方法
- 第三步匹配失败:获取bean,调用方法并执行,完成操作
- 第三步匹配成功:获取代理对象,根据代理对象的运行模式运行原始方法与增强的内容,完成操作。
注意:aop对toString方法进行了重写,当匹配成功,创建的是代理对象时,把这个代理对象打印出来会发现和普通对象一样。
切入点表达式
标准格式:动作关键字(访问修饰符 返回值 包名.类/接口名.方法名(参数)异常名)
execution (public User com.service.UserService.findById (int) )
- 动作关键字:描述切入点的行为动作,例如execution表示执行到指定切入点
- 访问修饰符:public,private等,可省略
- 返回值
- 包名
- 类/接口名
- 方法名
- 参数
- 异常名:方法定义中抛出指定异常,可省略
可以使用通配符快速描述
- * :单个独立的任意符号,可以独立出现也可以作为前缀或者后缀的匹配符出现(必有一个)
execution (public * com.User.*.UserService.find* (*) )
匹配com.User包下的任意包中的UserService类或接口中所有find开头的带有一个参数的方法
- .. :多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写(可以多个或0个)
execution (public User com..UserService.findById (..) )
匹配com包下的任意包中的UserService类或接口中所有名称为findById的方法
- + :专用于匹配子类类型
execution(* *..*Service+.*(..))
注意:
通知类型
环绕通知
如果原始方法的返回值不为空,那么环绕通知的方法也要返回值
注意:
在这里可以对返回值进行修改然后返回出去,如返回的时int类型的可以在返回的时候加点值进行返回,如原始方法返回的是100,这时环绕通知里返回的时候你加了200,那最终返回的值就是300。
获取通知数据
- 获取切入点方法的参数
- JoinPoint:适用于前置、后置、返回后、抛出异常后通知
- ProceedJoinPoint:适用于环绕通知
- 获取切入点方法返回值
- 返回后通知
- 环绕通知
- 获取切入点方法运行异常信息
- 抛出异常后通知
- 环绕通知
事务
作用
在数据层保障一系列的数据库操作同时成功或同时失败。
Spring事务作用
在数据层或业务层保障一系列的数据库操作同时成功或同时失败。
使用
在配置类里配置PlatformTransactionManager的事务管理器bean
在配置类里使用注解告知spring要用注解管理事务
然后可以使用注解进行事务管理了
事务属性
事务管理遇到异常回滚,但是对于一些特定异常是不会回滚的,像IOException异常是不会回滚的,这时就要通过rollbackFor设置一下了。