Spring框架
引入
为什么我们要使用框架呢?答案是为了简化开发。那么什么是框架呢?框架实际上是用于解决复杂问题的工具。
以砍木头为例,John用斧砍树,效率低,耗时多,大但是砍树枝比较方便;如果此时他要砍大量粗壮的树,斧不够用,所以此时他换用电锯,省时省力;编程也是同理,遇到一些简单的代码,我们自己写;如果遇到复杂的代码,就需要去借用框架。
软件框架是帮助程序员简化开发,提高效率的工具。
1. 什么是Spring框架?为什么要使用Spring框架?
Spring框架指的是Spring Framework,为基于Java开发的企业级应用提供便利,比如说在编码简洁性和配置部署方面。使用Spring框架的话,程序员将会将侧重点放在应用级的业务逻辑,无需关注部署环境等细节。
Spring框架能够简化开发主要体现在两个方面:
-
管理bean对象(IoC/DI) 。在引入Spring框架之前,创建对象都是在类内部进行,这样可能会造成的问题是:各个类之间相互依赖,高耦合;Spring框架实现了IoC框架,即将bean对象的控制权交给一个外部对象(Spring实现的IoC容器相当于一个管家,管理对象的创建等琐事);
-
面向切面编程(AOP)。AOP允许将遍布应用各处的功能分离出来形成可重用的组件,从而简化开发。
2. IoC
IoC是一种思想,将对象的控制权(创建)交给外部。
2.1 什么是IoC?
IoC :Inversion of Control,控制反转。是一种思想,即将创建对象的控制权交给外部环境(如:Spring框架中,将创建对象的控制权交给IoC容器)。
2.2 为什么要有IoC?
传统创建对象或实例化的方式是通过关键字new来实现,这种方式存在的弊端是耦合度高 。软件设计追求的是高内聚低耦合, 因此提出了用IoC容器(Spring提供)来实例化对象(创建并初始化对象)。
Spring中IoC思想的实现:将对象的控制权交给IoC容器管理,在使用的时候直接向IoC容器要即可。
在Spring中用来实现IoC的载体就是IoC容器 ,实际上是Map ,存放着各种对象(来自xml文件中配置的bean节点 ,包含@Repository,@Service,@Controller, @Component注解的类)。
2.3 如何实现IoC?
2.3.1 利用Spring框架创建对象
Spring中,Ioc核心思想就是把对象的控制权(包括创建和调用对象)交给IoC容器,Spring框架中,创建一个对象的步骤如下:
- pom文件中导入依赖Spring依赖坐标;
- 定义需要由Spring管理的类(接口);
- 创建Spring配置文件xxx.xml,配置相应类作为Spring管理的Bean;
xml文件中利用bean标签配置创建的对象,bean标签中包括两个关键属性,分别是id 和class 。id指的是对象的唯一标识 ,class指的是类标识。
bash
<bean id="对象标志" class="欲创建对象所属类的全限定名"></bean>
全限定名:目标类编译后class文件所在位置。
- 初始化IoC容器,通过容器获取Bean;
Bean对象是交给IoC容器管理的,所以要获取Bean,也要先初始化IoC容器,再getBean()获取;初始化容器两种方式:(1)ApplicationContext接口,(2)BeanFactory接口
【注】创建对象默认使用无参构造器
Spring中提供两种实现IoC容器的实现方式:
2.3.2 依赖注入
- 什么是依赖注入?
依赖注入(DI, Dependency Injection),建立bean之间的依赖关系,是一种具体的实现技术 ,类与类之间有依赖关系,在IoC容器运行期间,将某个依赖对象动态注入到当前对象的技术就叫做依赖注入.
- 如何实现依赖注入?
- 先删除new创建对象的代码
- 提供依赖对象相应的setter方法
- 在xml配置文件中配置两个Bean之间的关系
控制反转是一种思想,是能够解决问题的一种可能的结果,而依赖注入(Dependency Injection)就是其最典型的实现方法。由第三方(我们称作IoC容器)来控制依赖,将其通过构造函数、属性或者工厂模式等方法,注入到类A内,这样就极大程度的对类A和类B进行了解耦。
2.4 Spring Bean
Spring Bean是Spring容器管理的bean对象,容器初始化时注入到Spring应用程序中
定义方式:
- 配置文件中定义:
<bean>
- 注解定义:@Component/@Controller...
2.4.1 Spring Bean的配置
- 基础配置:
- 别名配置:
- 作用范围配置:
单例(singleton):在容器中只被实例化一次(加载spring配置文件的时候就会创建单实例对象),默认为单例模式;
多例(prototype):在容器中被调用几次就实例化几次(在调用getBean方法时会创建多实例对象)
2.4.2 Spring Bean的实例化
实例化Bean的三种方法:构造方法 /静态工厂/实例工厂 (FactoryBean)
2.4.3 Spring Bean的生命周期
Bean的生命周期:bean从创建到销毁这一过程,实例化-->属性赋值-->初始化-->使用中-->销毁。
2.5 依赖注入方式
-
setter注入:
<property>
简单类型-->value;引用类型-->ref -
构造方法注入:
<constructor-arg>
简单类型-->value;引用类型-->ref
- 开启自动装配的方式:
<bean>
标签中设置autowire属性,值为自动装配的方式; 自动装配优先级低于setter注入和构造器注入,同时出现时自动装配配置失效
2.6 注解开发
注解开发:替代配置文件中的各种标签,直接在对应类上添加注解
- @Component:相当于bean标签,用于创建对象
- @Repository:用于持久层类创建对象
- @Service:用于业务层类创建对象
- @Controller:用于控制器类创建对象
- @Value:给简单类型属性赋值,用于属性注入
- @Autowired:引用类型属性注入(自动注入byType)
- @Qualifier:与Autowired合用,属性自动注入,byName
- @Resource:自动注入,支持byName和byType,默认是byName
3. AOP
3.1 什么是AOP?
AOP(Aspect Oriented Programming),面向切面编程,是一种编程范式,用于指导开发者如何组织程序结构,可以类比OOP(Object Oriented Programming)面向对象编程。AOP主要作用是不惊动原始设计的基础上进行功能增强。
3.2 为什么引入AOP?
编写代码过程中,遇到代码重复的问题,一般来说有两种方式:
抽象成公共类/抽象成公共方法,这种一般称之为纵向抽取;
而如果遇到一种情况是,重复代码依附在业务逻辑代码中,有逻辑顺序,这种情况就没办法抽取成公共方法/公共类来消除重复代码,此时可以利用AOP思想,横向切割代码,将重复代码抽取出来,形成一个独立模块。
在不改变源码的情况下添加新功能,有利于减少系统的重复代码,降低模块之间的耦合度,有利于未来的可拓展性和可维护性。
【例子】获取某个活动的数据,根据条件发放奖励
\
3.3 AOP中的一些概念
- advice(通知):抽出来的方法;
- advice class(通知类):包含advice的类;
- joincut(连接点):有可能执行advice的方法;
- pointcut(切点):执行advice的方法;
- aspect(切面):建立advice与pointcut之间的绑定关系
4. 事务
4.1 什么是事务?
事务(Transaction)是逻辑上的一组操作,要么都执行,要么都不执行。
- 为什么要引入事务?
以转账为例,小红给小明转账100元,对于小红的账户来说,账户-100,对于小明的账户来说,账户+100;如果这两个操作之间出现了故障,就会导致转账出问题,为了解决类似这种问题,引入事务,将这两个操作看做一个整体,执行要么都成功,要么都失败。
4.2 事务的特性
事务的特性概括为:ACID
- A tomicity(原子性):事务中的操作,要不执行都成功,要不执行都失败;如果中途出现错误,则rollback(回滚),当作这个事务从未发生;
- C onsistency(一致性):事务执行前后数据库都保持一致性,也就是说:事务的执行是使数据从一个状态切换为另一个状态,但对于整个数据的完整性保持稳定;
- I solation(隔离性):并发环境间事务相互隔离,互不干扰;
- D urability(持久性 ):事务提交后,对数据库执行的变更是永久性的,不管数据库宕机或是故障,数据库能够重新启动就一定能恢复到事务成功时的状态
4.3 Spring对事务的支持
Spring 事务的本质,其实就是通过 Spring AOP 切面技术,在合适的地方开启事务,接着在合适的地方提交事务或回滚事务,从而实现了业务编程层面的事务操作。
Spring中使用事务:
4.4 Spring事务属性
4.5 Spring事务隔离级别
并发事务处理同一个数据时,不隔离的话,并发处理数据可能会出现一些问题:脏读/幻读/不可重复读,因此要设置隔离级别解决问题。
并发事务存在问题
事务隔离级别
- 数据库事务隔离级别
- Spring事务隔离级别
5. Spring常见注解及含义
5.1 创建对象
- @Component :通用的注解,可标注任意类为
Spring
组件。如果一个 Bean 不知道属于哪个层,可以使用@Component
注解标注; - @Controller:对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面;
- @Service: 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层;
- @Respository: 对应持久层即 Dao 层,主要用于数据库相关操作;
- @Bean:配置类中创建复杂对象
5.2 Bean作用域
- @Scope:声明 Spring Bean 的作用域
5.3 Bean生命周期
- @PostConstruct:初始化方法注解,作用在方法上。用来替换 bean 标签的 init-method 属性;
- @PreDestroy:销毁方法注解,作用在方法上。用来替换 bean 标签的 destory-method 属性
5.4 注入注解
- @Autowired:自动导入对象到类中,被注入进的类同样要被 Spring 容器管理。对象属性的依赖注入,自动注入byType;
- @Qualifier:与@Autowired联合使用,在按类型匹配的基础上,按名称匹配;
- @Resource:自动注入byName
5.5 配置
- @Configuration:声明配置类,替换 xml 配置文件;
- @ComponentScan:相当于 xml 配置文件中的注解扫描标签,用来扫@Component 等相关注解,组件扫描;
- @Import :一个配置类中导入另一个配置类;
- @Value :使用
@Value("${property}")
读取比较简单的配置信息
5.6 事务
- @Transactional :在要开启事务的方法上使用
@Transactional
注解即可
总结
6. Spring中的设计模式
7. Spring模块
参考资料
www.freecodecamp.org/news/what-i...
zhuanlan.zhihu.com/p/130915407
zhuanlan.zhihu.com/p/355778555