Spring
1.简介
- 作者:Rod Jahnson,悉尼大学的博士,然而他的专业不是计算机,而是音乐学
- 发展史:
1.2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架
2.2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版 - 核心思想:不重复发明轮子,而是"拿来主义",把业界做的最好的技术黏合起来形成一个强大的企业级的应用框架
- 理念:使现有技术更加实用 . 本身就是一个大杂烩 , 整合现有的框架技术
2.优点
- Spring是一个开源的免费框架(容器)
- Spring是一个轻量级的、非入侵式的框架
- 核心:IOC控制反转、DI依赖注入、Bean工厂、SpringAOP面向切面编程、事务控制
- 支持事务的处理,对框架整合的支持
- 总结: Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架
3.七大模块组成
- 核心容器(SpringCore)
- 应用上下文(Spring Context)
- Spring面向切面编程(Spring AOP)
- JDBC和DAO模块(Spring DAO)
- 对象实体映射(Spring ORM)
- Web模块(Spring Web)
- MVC模块(SpringWebMVC)
4.Spring Boot与Spring Cloud
- Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务
- Spring Cloud是基于Spring Boot实现的
- Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架
- Spring Boot使用了约束优于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置
- Spring Cloud很大的一部分是基于Spring Boot来实现,Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系
- SpringBoot在SpringClound中起到了承上启下的作用,如果你要学习SpringCloud必须要学习SpringBoot
5.核心概念
- BeanFactory:Spring内部使用,创建bean的工厂
- ApplicationContext:外部应用程序调用,也成为spring容器
- IoC控制反转Inversion of Control:开发者在无需自己new对象,无需关心对象的创建过程User user = new User(); 手动创建对象User user = context.getBean(user); 容器创建对象
- DI依赖注入Dependency Injection:松耦合方式实现对象直接的依赖
- AOP面向切面编程:补充java面向对象的不足
6.三大核心组件
- Bean:
Bean 包装的是 Object,而 Object 必然有数据 - Context
1.如何给这些数据提供生存环境就是 Context要解决的问题
2.对 Context 来说它就是要发现每个 Bean 之间的关系,为它们建立这种关系并且要维护好这种关系
3.所以 Context 就是一个Bean关系的集合,这个关系集合又叫 Ioc 容器,一旦建立起这个 Ioc 容器后 Spring 就可以为你工作了 - Core
Core 就是发现、建立和维护每个 Bean 之间的关系所需要的一些类的工具
7.IOC理论
7.1 IOC原型
- 以前所有东西都是由程序去进行控制创建 , 而现在是由我们自行控制创建对象 , 把主动权交给了调用者 . 程序不用去管怎么创建,怎么实现了 . 它只负责提供一个接口
- 这种思想 , 从本质上解决了问题 , 我们程序员不再去管理对象的创建了 , 更多的去关注业务的实现 . 耦合性大大降低
7.2 IOC本质
- 控制反转IOC(Inversion of Control),是一种设计思想
- DI(依赖注入)是实现IOC的一种方法
- 没有IOC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方
- IOC是Spring框架的核心内容,使用多种方式完美的实现了IOC,可以使用XML配置,也可以使用注解
- Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象
- 采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的
- 控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)
7.3 实现原理
- 控制反转
1.控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
2.反转 : 程序本身不创建对象 , 而变成被动的接收对象 - 依赖注入 : 就是利用set方法来进行注入的
- IOC是一种编程思想,由主动的编程变成被动的接收
- 可以通过newClassPathXmlApplicationContext去浏览一下底层源码
- 所谓IOC,就是:对象由Spring 来创建 , 管理 , 装配
7.4 IOC和DI
- 概念
1.IOC简单来说就是将对象Object的创建的权力及对象的生命周期的管理过程交由Spring框架来处理,从此在开发过程中不在需要关注对象的创建和生命周期的管理,而是在需要的时候由Spring框架提供,这个由Spring框架管理对象创建和生命周期的机制称之为控制反转
2.在创建对象的过程中Spring可以依据对象的关系,自动把其它对象注入(无需创建对象,直接拿着使用)进来,这个过程称之为DI(Dependency Injection)依赖注入 - Spring核心
1.创建对象
2.设置对象的关联关系 - IOC(Inversion of Control),控制反转
就是指将对象的创建,对象的存储(map),对象的管理(依赖查找,依赖注入)交给了spring容器 - DI(Dependency Injection)依赖注入
1.依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源
2.注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配
3.相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中
7.5 Bean
- 自动装配
1.自动装配是使用spring满足bean依赖的一种方法
2.spring会在应用上下文中为某个bean寻找其依赖的bean - 装配机制(三种)
1.在xml中显式配置
2.在java中显示配置
3.隐式的bean发现机制和自动装配 - Spring的自动装配需要从两个角度来实现
1.组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean
2.自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI - 拓展:
1.组件扫描和自动装配组合发挥巨大威力,使的显示的配置降低到最少
2.推荐不使用自动装配xml配置 , 而使用注解
7.6 注解
7.6.1 xml和注解
- xml用来管理bean
- 注解只负责完成属性的注入
7.6.2 注入bean的注解
- @Autowired
1.@Autowired: 由bean提供, 是按类型自动转配的,不支持id匹配
2.@Autowired可以作用在变量、setter方法、构造函数上 - @Qualifier
1.@Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
2.@Qualifier不能单独使用 - @Resource
1.@Resource如有指定的name属性,先按该属性进行byName方式查找装配
2.其次再进行默认的byName方式进行装配
3.如果以上都不成功,则按byType的方式自动装配 - 拓展:@Autowired与@Resource异同
1.@Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上
2.@Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
3.@Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配
4.它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName
7.6.3 使用注解开发
- 说明
1.在spring4之后,想要使用注解形式,必须得要引入aop的包
2.在配置文件当中,还得要引入一个context约束 - Bean的实现
1.我们之前都是使用 bean 的标签进行bean注入,但是实际开发中,我们一般都会使用注解
2.@Component(“user”):相当于配置文件中 <bean id=“user” class=“当前注解的类” - 属性注入
1.使用注解注入属性
2.可以不用提供set方法,直接在直接名上添加@value(“值”)
3.@Value(“派大星”):相当于配置文件中 <property name=“name” value=“派大星”
4.如果提供了set方法,在set方法上添加@value(“值”) - 衍生注解
1.说明:这些注解,就是替代了在配置文件当中配置步骤而已!更加的方便快捷
2.@Component三个衍生注解:@Controller:web层,@Service:service层,@Repository:dao层
3.写上这些注解,就相当于将这个类交给Spring管理装配了
7.6.4 小结
- XML与注解比较
1.XML可以适用任何场景 ,结构清晰,维护方便
2.注解不是自己提供的类使用不了,开发简单方便 - xml与注解整合开发
1.xml管理Bean
2.注解完成属性注入
3.使用过程中, 可以不用扫描,扫描是为了类上的注解 - 作用
1.进行注解驱动注册,从而使注解生效
2.用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册
3.如果不扫描包,就需要手动配置bean
4.如果不加注解驱动,则注入的值为null
7.7 IOC小结
- 之前我们自己new出新类。new User();变成由一个初始化的xml配置文件来创建,也就是由spring容器来创建
- 遍历xml配置文件,读取到,获取到class属性的类的全路径,利用反射创建这个类
- 在java范畴中万物皆Object,在Spring中万物皆Bean。Bean是Spring的核心、基础、根源
- IOC有三个核心:BeanFactory、反射、DI。BeanFactory利用反射实现对象的创建,DI实现对象关系管理
7.代理模式
- AOP的底层机制就是动态代理
7.1 静态代理
- 角色分析
1.抽象角色 : 一般使用接口或者抽象类来实现
2.真实角色 : 被代理的角色
3.代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作
4.客户 : 使用代理角色来进行一些操作 - 优点
1.可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情
2.公共的业务由代理来完成 . 实现了业务的分工
3.公共业务发生扩展时变得更加集中和方便 - 缺点
类多了 , 多了代理类 , 工作量变大了 . 开发效率降低
7.2 动态代理
- 我们想要静态代理的好处,又不想要静态代理的缺点,所以 , 就有了动态代理
- 动态代理的角色和静态代理的一样
- 动态代理的代理类是动态生成的 . 静态代理的代理类是我们提前写好的
- 动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理
1.基于接口的动态代理——JDK动态代理
2.基于类的动态代理—cglib
3.现在用的比较多的是 javasist 来生成动态代理 - 核心
1.一个动态代理 , 一般代理某一类业务
2.一个动态代理可以代理多个类,代理的是接口! - 优点
1.一句话总结:静态代理有的它都有,静态代理没有的,它也有
2.可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情
3.公共的业务由代理来完成 . 实现了业务的分工
4.公共业务发生扩展时变得更加集中和方便
5.一个动态代理 , 一般代理某一类业务
6.一个动态代理可以代理多个类,代理的是接口
8.AOP面向切面编程
8.1 什么是AOP
- 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
- AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
- 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
8.2 概念
- Spring核心特征中除了IoC控制反转、DI依赖注入,还有一个核心就是强大的面向切面编程AOP(Aspect Oriented Programming)的实现
- Spring AOP有三要素
1.Aspect定义切面
2.通过通知(Advice)来指定具体做什么事情。如方法执行前做什么,方法执行后做什么,抛出异常做什么,从而实现对象行为(方法)的增强
3.具体通过切点(PointCut)配置切点表达式(expression)来指定在哪些类的哪些方法上织入(ware)横切逻辑;被切的地方叫连接点(JoinPoint)
8.3 AOP在Spring中的作用
- 提供声明式事务;允许用户自定义切面
1.横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等
2.切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类
3.通知(Advice):切面必须要完成的工作。即,它是类中的一个方法
4.目标(Target):被通知对象
5.代理(Proxy):向目标对象应用通知之后创建的对象
6.切入点(PointCut):切面通知 执行的 “地点”的定义
7.连接点(JointPoint):与切入点匹配的执行点
8.4 通知advice
- Spring框架实现了AOP面向切面,其引入了第三方AspectJ框架来具体实现
- AspectJ提供了五种切入方式
1.前置通知before
2.后置通知after
3.环绕通知around
4.返回后通知afterReturning
5.异常通知afterThrowing
8.4 小结
- Spring的Aop就是将公共的业务 (日志 , 安全等) 和领域业务结合起来 , 当执行领域业务时 , 将会把公共业务加进来 . 实现公共业务的重复利用 . 领域业务更纯粹 , 程序猿专注领域业务 , 其本质还是动态代理
9.声明式事务
9.1 事务说明
- 事务在项目开发过程非常重要,涉及到数据的一致性的问题
- 事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性
- 事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用
9.2 Spring中的事务管理
- Spring在不同的事务管理API之上定义了一个抽象层,使得开发人员不必了解底层的事务管理API就可以使用Spring的事务管理机制
9.3 Spring支持编程式事务管理和声明式的事务管理
- 编程式事务管理
1.将事务管理代码嵌到业务方法中来控制事务的提交和回滚
2.缺点:必须在每个事务操作业务逻辑中包含额外的事务管理代码 - 声明式事务管理
1.一般情况下比编程式事务好用
2.将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理
3.将事务管理作为横切关注点,通过aop方法模块化。Spring中通过Spring AOP框架支持声明式事务管理
9.4 事务管理器
- 无论使用Spring的哪种事务管理策略(编程式或者声明式)事务管理器都是必须的
- 就是 Spring的核心事务管理抽象,管理封装了一组独立于技术的方法
9.5 spring事务传播特性
- 事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。spring支持7种事务传播行为
1.propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择
2.propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行
3.propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常
4.propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起
5.propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
6.propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常
7.propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作