Spring框架
2021-11-09 14:59:06 32 举报
AI智能生成
Spring框架脑图
作者其他创作
大纲/内容
Spring概述
什么是Spring框架
Spring的优良特性
非侵入式
Spring开发的应用中的对象可以不依赖于Spring的API
依赖注入
反转控制(IOC)最经典的实现
面向切面
AOP功能,方便进行面向切面的编程
容器
Spring是一个容器,因为它包含并且管理应用对象的生命周期
组件化
Spring 中可以使用XML和Java注解组合这些对象
支持声明式事务处理
通过配置就可以完成对事务的管理,不需要手动编程
集成各种优秀框架
Spring不排斥各种优秀的开源框架,内部提供了对各种优秀框架的支持
组成模块
架构图
分支主题
核心组件:Core,Context,Beans
搭建Spring运行时环境
创建项目
maven项目
在pom中增加依赖
普通web项目
手动添加jar包到项目路径下
创建配置文件
applicationContext.xml
使用Spring框架
使用spring框架创建对象,给属性赋值
IOC控制反转/DI依赖注入
什么是IOC
IOC和DI的关系
IOC容器在Spring框架的实现
bean对象获取的方式
ApplicationContext的getBean()方法,根据id(配置的id对应)来获取bean的实例
未知目标类型,需要类型强转
ApplicationContext的getBean()方法,bean的类型,来获取bean的实例
容器中只有一个对应类型bean,可以正常
容器中有多个对象类型的bean,异常
ApplicationContext的getBean()方法,bean的id值和类型,来获取bean的实例
唯一匹配
依赖注入的几种方式
通过bean的setXxx()方法赋值
bean的实体类中,必须提供setter方法
通过bean的构造器赋值
bean的实体类中,必须提供空参和带参构造方法
p命名空间注入属性值
Spring从2.5版本开始引入了一个新的p命名空间,可以通过<bean>元素属性的方式配置Bean 的属性
对于直接量(基本数据类型、字符串)属性:p:属性名="属性值"
对于引用Bean的属性:p:属性名-ref="Bean的id"
引用其他的bean
内部bean的使用
外部已声明的bean
工厂bean的使用
Spring中有两种类型的bean,一种是普通bean,另一种是工厂bean,即FactoryBean。
工厂bean跟普通bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂bean的getObject方法所返回的对象。
工厂bean必须实现org.springframework.beans.factory.FactoryBean接口。
bean的作用域 *
单例:singleton
所有bean的默认作用域
多例:prototype
请求:request
会话:session
bean的生命周期 *
作用
Spring IOC容器可以管理bean的生命周期,Spring允许在bean生命周期内特定的时间点执行指定的任务
过程
① 通过构造器或工厂方法创建bean实例
② 为bean的属性设置值和对其他bean的引用
③ 调用bean的初始化方法
④ bean可以使用了
⑤ 当容器关闭时,调用bean的销毁方法
使用
在配置bean时,通过init-method和destroy-method 属性为bean指定初始化和销毁方法
bean的后置处理器
bean后置处理器允许在调用初始化方法前后对bean进行额外的处理
bean后置处理器对IOC容器里的所有bean实例逐一处理,而非单一实例。其典型应用是:检查bean属性的正确性或根据特定的标准更改bean的属性。
bean后置处理器时需要实现接口: org.springframework.beans.factory.config.BeanPostProcessor
添加bean后置处理器后bean的生命周期变为7个
①通过构造器或工厂方法创建bean实例
②为bean的属性设置值和对其他bean的引用
③将bean实例传递给bean后置处理器的postProcessBeforeInitialization()方法
④调用bean的初始化方法
⑤将bean实例传递给bean后置处理器的postProcessAfterInitialization()方法
⑥bean可以使用了
⑦当容器关闭时调用bean的销毁方法
Spring的装配方式 *
手动装配
以value或ref的方式明确指定属性值都是手动装配
自动装配 *
根据指定的装配规则,不需要明确指定,Spring自动将匹配的属性值注入bean中。
根据类型自动装配:byType
使用bean的属性的类型与IOC容器中<bean>的class进行匹配。 如果唯一匹配则装配成功
如果匹配到多个兼容类型的bean。则抛出异常
根据名称自动装配:byName
使用bean的属性名与IOC容器中<bean>的id值进行匹配. 匹配成功则装配成功.
constructor:通过构造器进行自动装配,no:不进行自动装配(关闭),default:使用父标签beans配置的装配方式(default-autowire指定的装配方式)
注解实现自动装配(必须掌握) *
相对于XML方式而言,通过注解的方式配置bean更加简洁和优雅,而且和MVC组件化开发的理念十分契合,是开发中常用的使用方式。
分层注解
普通组件:@Component
标识一个受Spring IOC容器管理的组件,比如有个类要交给spring的Ioc容器管理,只要在类上加这个注解就可以了,这个只是普通的组件,没有特殊含义
持久化层组件:@Repository
标识一个受Spring IOC容器管理的持久化层组件
业务逻辑层组件:@Service
标识一个受Spring IOC容器管理的业务逻辑层组件
控制层/表述层控制器组件:@Controller
标识一个受Spring IOC容器管理的表述层控制器组件
组件命名规则
默认情况:使用组件的简单类名首字母小写后得到的字符串作为bean的id
使用组件注解的value属性指定bean的id
注意:事实上Spring并没有能力识别一个组件到底是不是它所标记的类型,即使将@Respository注解用在一个表述层控制器组件上面也不会产生任何错误,所以 @Respository、@Service、@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色,在使用上基本是没有区别的。
组件扫描
组件被上述注解标识后还需要通过Spring进行扫描才能够侦测到
核心配置文件增加配置:<context:component-scan base-package="com.kgc.spring.annotation"></context:component-scan>
扫描加了注解的类,并管理到IOC容器中 base-package: 基包. Spring会扫描指定包以及子包下所有的类,将带有注解的类管理到IOC容器中当需要扫描多个包时可以使用逗号分隔
指定扫描和排除扫描
指定扫描
<context:include-filter>子节点表示要包含的目标类
通常需要与父标签的use-default-filters属性配合使用才能够达到“仅包含某些组件”这样的效果。即:通过将use-default-filters属性设置为false,禁用默认过滤器,然后扫描的就只是include-filter中的规则指定的组件了。否则不生效
排除扫描
<context:exclude-filter>子节点表示要排除在外的目标类
过滤扫描方式
根据注解
按照注解方式进行指定,注意type和expression(注解的全类名),推荐用法
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
根据类型
按照指定类进行指定,注意type和expression(具体类的全类名)
<context:include-filter type="assignable" expression="com.kgc.spring.annotation.controller.Controller"/>
组件自动装配
需求:Controller组件中往往需要用到Service组件的实例,Service组件中往往需要用到 Repository组件的实例。Spring可以通过注解的方式帮我们实现属性的装配。
原理:在指定要扫描的包时,<context:component-scan> 元素会自动注册一个bean的后置处 理器:AutowiredAnnotationBeanPostProcessor的实例。该后置处理器可以 自动装配标记 了@Autowired、@Resource或@Inject注解的属性。
@Autowired注解
工作机制
首先会使用byType的方式进行自动装配,如果能唯一匹配,则装配成功,
如果匹配到多个兼容类型的bean,还会尝试使用byName的方式进行唯一确定
如果能唯一确定,则装配成功,如果不能唯一确定,则装配失败,抛出异常.
属性配置
默认情况下, 使用@Autowired标注的属性必须被装配,如果装配不了,也会抛出异常
可以设置@Autowired注解的required属性为 false,实现允许不必须被装配(容器中找不到的情况,如果多个匹配,不适用)
@Qualifier注解
如果匹配到多个兼容类型的bean,可以使用@Qualifier来进一步指定要装配的bean的id值
在自动装配的成员对象变量上,增加注解:@Qualifier("目标bean的idl")
@Resource注解
Resource注解,也可以实现自动装配,但是这个不是spring的注解,是jdk提供的,实现自动装配原理,正好跟Autowired注解是相反的(先根据名称,再根据类型)
提供一个bean名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为bean的名称。
@Inject注解
@Inject和@Autowired注解一样也是按类型注入匹配的bean,但没有required属性
了解即可
AOP面向切面
前奏
数学计算器
执行加减乘除运算
在程序执行期间追踪正在发生的活动(记录日志)
此种实现方式分析
概述
1) AOP(Aspect-Oriented Programming,面向切面编程):是一种新的方法论,是对传统 OOP(Object-Oriented Programming,面向对象编程)的补充。
2) AOP编程操作的主要对象是切面(aspect),而切面模块化横切关注点(可以理解为功能)。 在应用AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能应用在哪里,以什么方式应用,并且不必修改受影响的类。这样一来横切关注点就被模块化到特殊的类里——这样的类我们通常称之为“切面”。
3) AOP的好处: ① 每个事物逻辑位于一个位置,代码不分散,便于维护和升级 ② 业务模块更简洁,只包含核心业务代码
实现模式
使用动态代理
代理设计模式的原理:使用一个代理对象将原始对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
术语
切面(Aspect)
封装了各个抽离的功能点的类,Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中
增强(Adivce)
也被翻译成通知,增强包含了用于添加到目标连接点上的一段执行逻辑,又包含了用于定位连接点的方位信息也就是需要执行的具体操作,简单理解为切面中的一个方法
切入点(Pointcut)
定义义了“故事”发生的地点。例如某个类或者方法名,Spring中允许我们使用正则来指定
连接点(Joinpoint)
切入点匹配的执行点称作连接点。如果说切入点是查询条件,那连接点就是被选中的具体的查询结果(具体的数据记录)。简单记忆,就是业务类中的各个方法中执行增强的位置。
代理(Proxy)
AOP框架创建的对象。一个类被AOP织入增强之后,就产生了一个结果类,它是融合了原类和增强逻辑的代理类。
目标对象(Target)
增强逻辑的织入的目标类
说明:
切面可以理解为由增强处理和切入点组成,既包含了横切逻辑的定义,也包含了连接点的定义。面向切面编程主要关心两个问题,即:在什么位置,执行什么功能。
能做哪些事
Spring声明式事务管理配置
Controller层的参数校验
在执行方法前,判断是否具有权限
信息过滤,页面转发等等功能
环境搭建
普通项目
手动添加jar包
maven项目
添加依赖
使用AspectJ注解声明切面
引入aop名称空间,增加配置
<!-- 组件扫描 --><context:component-scan base-package="com.kgc.spring.aspectj"></context:component-scan>
<aop:aspectj-autoproxy/>
基于注解使用AspectJ: 主要的作用是当Spring IOC容器侦测到bean配置文件中的<aop:aspectj-autoproxy>元素时,会自动为 与AspectJ切面匹配的bean创建代理
@Aspect注解
要在Spring中声明AspectJ切面,只需要在IOC容器中将切面声明为bean实例。使用Component
当在Spring IOC容器中初始化AspectJ切面之后,Spring IOC容器就会为那些与 AspectJ切面相匹配的bean创建代理。
在AspectJ注解中,切面只是一个带有@Aspect注解的Java类,它往往要包含很多通知。
通知是标注有某种注解的简单的Java方法
AspectJ支持5种类型的通知注解
① @Before:前置通知,在方法执行之前执行
② @After:后置通知,在方法执行之后执行
不管目标方法有没有抛出异常
无法获取返回结果
③ @AfterRunning:返回通知,在方法返回结果之后执行
可以获取到方法的返回值
通过returning属性 来指定一个名字, 必须要与当前方法的一个形参名一致.
④ @AfterThrowing:异常通知,在方法抛出异常之后执行
通过throwing属性来指定一个名字, 必须要与当前方法的一个形参名一致.
⑤ @Around:环绕通知,围绕着方法执行
可以理解是 前置 后置 返回 异常 通知的结合体
切入点表达式
语法
execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表]))
举例
execution(* com.kgc.spring.aspectJ.annotation.*.*(..))
含义
通知要作用的目标包下的所有类中的所有类的所有方法
第一个 * : 任意修饰符 任意返回值
第二个 * : 任意类
第三个 * : 任意方法
.. : 任意参数列表
重用切入点表达式
同一个切点表达式可能会在多个通知中重复出现
通过@Pointcut注解将一个切入点声明成简单的方法
@Pointcut("execution(* com.kgc.spring.aspectJ.annotation.*.*(..))")public void declarePointCut() {}
目标通知直接指定方法名就可以了,如:@After("declarePointCut()")
切面优先级
通过注解@Order(值)改变优先级
默认int类型最大值 2147483647 值越小优先级越高
声明式事务
什么是事务
事务就是一组由于逻辑上紧密关联而合并成一个整体(工作单元)的多个数据库操作,这些操作要么都执行,要么都不执行
事务的特性(ACID)
原子性(atomicity)
“原子”的本意是“不可再分”,事务的原子性表现为一个事务中涉及到的多个操作在逻辑上缺一不可。事务的原子性要求事务中的所有操作要么都执行,要么都不执行
一致性(consistency)
“一致”指的是数据的一致,具体是指:所有数据都处于满足业务规则的一致性状态。一致性原则要求:一个事务中不管涉及到多少个操作,都必须保证事务执行之前数据是正确的,事务执行之后数据仍然是正确的。如果一个事务在执行的过程中,其中某一个或某几个操作失败了,则必须将其他所有操作撤销,将数据恢复到事务执行之前的状态,这就是回滚。
隔离性(isolation)
在应用程序实际运行过程中,事务往往是并发执行的,所以很有可能有许多事务同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。隔离性原则要求多个事务在并发执行过程中不会互相干扰。
持久性(durability)
持久性原则要求事务执行完成后,对数据的修改永久的保存下来,不会因各种系统错误或其他意外情况而受到影响。通常情况下,事务对数据的修改应该被写入到持久化存储器中。
事务的分类
编程式事务管理
使用步骤
①获取数据库连接Connection对象 ②取消事务的自动提交 ③执行操作 ④正常完成操作时手动提交事务 ⑤执行失败时回滚事务 ⑥关闭相关资源
优缺点
编程式事务管理需要将事务管理代码嵌入到业务方法中来控制事务 的提交和回滚。在使用编程的方式管理事务时,必须在每个事务操作中包含额外的事务 管理代码。相对于核心业务而言,事务管理的代码显然属于非核心业务,如果多个模块都使用同样模式的代码进行事务管理,显然会造成较大程度的代码冗余
声明式事务管理
大多数情况下声明式事务比编程式事务管理更好:它将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。
Spring在不同的事务管理API之上定义了一个抽象层,通过配置的方式使其生效,从而让应用程序开发人员不必了解事务管理API的底层实现细节,就可以使用Spring的事务管理机制。
事务管理器
定义
Spring从不同的事务管理API中抽象出了一整套事务管理机制,让事务管理代码从特定的事务技术中独立出来。开发人员通过配置的方式进行事务管理,而不必了解其底层是如何实现的。
Spring的核心事务管理抽象是PlatformTransactionManager。它为事务管理封装了一组独立于技术的方法。无论使用Spring的哪种事务管理策略(编程式或声明式),事务管理器都是必须的。
事务管理器可以以普通的bean的形式声明在Spring IOC容器中
实现
1) DataSourceTransactionManager:在应用程序中只需要处理一个数据源,而且通过JDBC存取。2) JtaTransactionManager:在JavaEE应用服务器上用JTA(Java Transaction API)进行事务管理,基本不用3) HibernateTransactionManager:用Hibernate框架存取数据库,不涉及
事务的传播行为
当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。
@Transactional注解的propagation属性中定义
Propagation.REQUIRED 默认值. 使用调用者的事务(全程一个事务)
Propagation.REQUIRES_NEW 将调用者的事务挂起, 重新开启事务来使用.
其它的行为作为了解
事务的隔离级别
数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。
@Transactional注解的isolation属性中定义
读未提交:READ UNCOMMITTED
读已提交:READ COMMITTED
oracle默认的隔离级别
可重复读:REPEATABLE READ
Mysql默认的隔离级别
串行化:SERIALIZABLE
0 条评论
下一页