我认为Spring的学习任重而道远,他颠覆了传统EJB的开发,将JavaEE企业级开发引向了另一个高峰。无论时后来的Spring Boot还是后面的Spring Cloud都是Spring一家的。很多人都说可以不用学习Spring直接上手SpringBoot,我觉得没错,就像我最开始没有学习JavaWeb直接上手框架一样,虽然都能学,但是对于大部分人来说,中间少一个过渡的东西,总归是有些知其然不知其所以然的感觉。Spring一定要研究明白,有想法的可以去扒一扒他的源码,据说还是很有些东西的。Spring能历经16年,并且发展的越来越大,我想还是有一定的道理。IOC部分代码编写和思想的理解同样重要,AOP的侧重思想的理解,代码初看你肯定觉得复杂,但是想明白了道理,其实也就是那几行死的不能再死的代码!!!
文章目录
1、概述
2004年出现。
优点:
- Spring是一个开源的免费的框架(容器)
- Spring是一个轻量级的、非侵入式的框架
- 控制反转(IOC)、面向切面编程(AOP)
- 支持事务的处理,对框架整合的支持
Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架
由七大模块组成:Spring Core、Spring DAO、Spring Context、Spring Web、Spring ORM、Spring AOP、Spring Web MVC
按道理我们JavaWeb学习完,就可以进行企业级的开发了,但是由于开发起来过于复杂,便衍生出了框架。按道理框架的开发已经足够简单了,缺实,现在很多企业还是使用的SSM进行开发的。但是我们后面会发现SSM的配置也由简变杂,便衍生出了SpringBoot、Spring Cloud,继而让不断扩大的公司转战微服务架构(此时我的是MVC架构)。所以未来的发展是
SpringBoot构建一切,SpringCloud协调一切,SpringCloud Date Flow连接一切
这也是我们接下来微服务需要学习的东西。
2、IOC理论
很多公司面试的时候都喜欢问,谈谈你对IOC的理解!!!甚至还有DI。
简单来说就是,IOC(Inversion of Control)是一种设计的方式(类比设计模式)。我们最开始学习java的时候编写代码,总是喜欢new对象,现在IOC提供了一种new对象的方式,就是不再需要我们去new,而是Spring容器帮我们去做,我们要做的就是放进去,需要就去拿。设想一下,你有好几个类,你每一个类都去new同样的东西,为什么不把这些对象找一个容器放起来,然后我们需要就去拿?而IOC就是做这个工作。曾经选择new不new对象,决定权在我们,现在我们只需要放进去,拿不拿对象出来用,决定权在我们。即我们获取对象的方式发生了变化,中间多了一层。
DI(Dependency Injection)有些地方说这两个是同一个东西,但是我们不看概念,看他们的效果,我觉得是不一样的。DI就是将数据进行注入,将对象放进了那个Spring大容器中。IOC明显是侧重整个过程的效果,而DI则侧重放进去这一部分。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的就是IOC容器,其实现方法就是依赖注入
3、编写程序
编写一个简单的spring程序步骤:
- 编写pojo类
- 将pojo类注入到spring容器中
- 测试类获取对应的bean,进行测试
4、Spring配置
4.1、别名
我们可以为我们注入的Bean设置一个别名,这样我们在获取的时候就可以通过别名获取对应的Bean。可以单独配置,也可以在Bean的配置里面进行配置。
4.2、Bean配置
这是DI的关键,我们就是配置Bean,以此能够完成属性的注入。当然,除了属性的注入,还是有id(我们的Bean的名字)、class(注入的pojo类的位置)、name(配置别名)甚至是scope的配置
4.3、import的使用
前期我们可能感觉不出来他的使用位置。由于我们的代码编写是按层次来编写的,每一层的配置文件都是需要使用IOC的方式进行,然后我们会配置一个大的applicationContext.xml,他的作用就是用来汇总其他几层的信息bean,继而达到我们的集中管理。
5、依赖注入
前面的Bean的配置,完成了DI的一个大致框架,接下来的这部分知识板块就是完成具体的信息注入。
前面也说了,我们不再需要手动new对象了,那我们的想要传递数据到对象怎么办?
原来我们是使用带参构造方法,或者是set的方式进行传入。依赖注入就是这个过程。
注入属性使用value,注入对象使用ref
5.1、构造器注入
构造器的带参构造方法有三种形式:
- 利用数据的index下标进行传值
- 利用数据的类型进行传值
- 利用数据的名字进行传值
5.2、set注入
我觉得看懂代码就懂了
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--注册Bean-->
<bean id="address" class="pers.mobian.pojo.Address">
<property name="address" value="重庆"></property>
</bean>
<bean id="student" class="pers.mobian.di.Student">
<!--1、普通注入-->
<property name="name" value="默辨"></property>
<!--2、Bean对象注入-->
<property name="address" ref="address"></property>
<!--3、数组注入-->
<property name="books">
<array>
<value>《人间失格》</value>
<value>《活着》</value>
<value>《浪潮之巅》</value>
</array>
</property>
<!--4、list集合注入-->
<property name="hobbys">
<list>
<value>跑步</value>
<value>打游戏</value>
</list>
</property>
<!--5、map集合注入-->
<property name="card">
<map>
<entry key="IDCard" value="1234567890"></entry>
<entry key="BankCar" value="987654321"></entry>
</map>
</property>
<!--6、set集合注入-->
<property name="game">
<set>
<value>LOL</value>
<value>CF</value>
</set>
</property>
<!--7、null值注入-->
<property name="wife">
<null></null>
</property>
<!--8、property注入-->
<property name="info">
<props>
<prop key="administrator">[email protected]</prop>
<prop key="support">[email protected]</prop>
<prop key="development">[email protected]</prop>
</props>
</property>
</bean>
</beans>
5.3、其他注入方式
我们将前面的两种注入方式进行化简,可以使用c(构造器注入)、p(set注入)命名空间的方式进行依赖注入
<bean id="people1" class="pers.mobian.pojo.People" p:age="22" p:name="mobian"></bean>
<bean id="people2" class="pers.mobian.pojo.People" c:age="22" c:name="默辨"></bean>
<bean id="people3" class="pers.mobian.pojo.People" c:_0="mobian" c:_1="11"></bean>
5.4、Bean的作用域
Spring默认的配置是单例模式,我们可以对其进行修改,在Bean的配置中我们已经说过,它是和id、class、name同级的,所以我们只需要在对应的位置添加scope=“xx”,即可
6、Bean的自动装配
自动装配,就好比我们怎么把对象放进容器,重在通过哪种方式
- ByName
- ByType
- 使用注解
重点是第三种使用注解进行自动装配。因为我们后面的SpringBoot学习还需要,所以一定要学会灵活使用。
使用注解自动装配,又可以分成使用Spring的注解和Java原生的注解
Spring附带的注解的使用步骤:
- 导入约束以及开启注解支持
- @Autowired 该注解表示自动注入,用在属性上,这样我们就可以不再去xml中进行DI,直接使用注解完成DI
- @Nullable 该注解可以在使用在构造方法上,使对用的属性可以为null
- @Qualifier 该注解表示可以指定需要装配的bean(@Autowired是通过ByNmae进行自动注入,如果名字找不到,就会报错)
@Qualifier 与@Autowired可以结合起来使用,为属性指定内容
Java原生的注解使用:
- 直接在属性上使用
- @Resource(name = “xx”)
@Resource和@Autowired的区别:
- 都是用来自动装配的,都可以放在属性字段上面
- @Autowired通过bytype的方式实现,而且必须要求这个对象存在(常用)
- @Resource默认通过byname的方式实现,如果找不到就通过bytype实现,如果两个都找不到的情况下就会报错
- 执行顺序:@Autowired通过bytype的方式实现。@Resource默认通过byname的方式实现
7、使用注解开发
使用注解开发的步骤:
- 导入aop的依赖
- 在xml配置文件中添加对应的注解支持,以及包路径的扫描
- 编写实体类,使用注解将类进行自动装配(@Component)
- 测试类进行测试
@Component的衍生注解,在web开发过程中,会按照MVC三层架构分层
- dao(@Repository)
- service(@Service)
- controller(@Controller)
这些注解我们后面都会接触到的!
我们只需要使用对应的注解,然后在xml配置文件中进行对应的扫描,即可完成对应的Bean的装配。当然我们前面说的那些都能够通过注解的方式进行注入。
作用域:@Scope
属性的注入:@Value
Bean对象的注入:@Component
直接注入Bean:@Bean
扫描类下的包:@ComponentScan
我们不难发现,xml可以用来配置Bean,我们也可以使用注解配置Bean,那我们怎么分配他们呢?
这里给出一个我认为的最佳实践:xml用来管理bean,注解只负责属性的注入。
8、使用Java的方式来配置Spring
其实我们在Spring阶段的学习,使用前面的方式来配置Bean完全已经够用了,但是我们后面学习SpringBoot的时候,我们会发现,我们需要使用各种各样的配置,到时候这种方式就会比较常见,所以这里我们需要掌握配置方法,为接下来的学习打好基础。
中心思想就是将我们的xml配置文件转换成java配置类
使用配置类配置步骤:
- 编写一个实体类,并用注解自动注入属性及放入Spring容器中
- 编写一个java配置类。我们需要使用注解@ComponentScan()扫描对应的类路径,以及使用@Configuration注解表明我门是一个配置类
- 测试类测试
使用xml配置文件能用的方式,我们的配置类都能做,只需要使用不同的注解即可。
说实话,最开始我学习这个的时候,感觉一脸懵逼,只是看着敲。学完了SpringBoot回头再来复习的时候,感觉也就那么回事。主要就是对于注解的理解和概念的理解!!!
9、AOP
AOP的底层是代理模式,这个需要自己去学习,因为面试官也很喜欢问AOP
AOP(Aspect Oriented Programming),中文名为面向切面编程。
我们假设一个场景,我们现在的程序已经能够上线奔跑了,突然甲方想加一个什么功能,如果使用传统的方式,我们很有可能代码编写好后,由于与之前的代码发生冲突,导致整个项目崩盘,这是我们大家都不希望看到的。基于此,Spring的AOP来了,他以一个横切的角度,在不改变原先代码正常奔跑的基础上,切进来一个功能,而这个功能就是我们希望的。这些功能很多,最常见的就是添加日志功能。
虽然我们自己也能够使用代理模式的方式进行代码的添加,但是Spring的AOP为我们提供了一个较好的切入的模板,让我们的代码能够更加方便的进行切入。
三种实现AOP的方法
使用原生的SpringAPI接口:
- 导入对应的织入包
- 导入相关的约束
- 实现对应的接口在编写我们希望实现的功能的方法体
- 配置到xml配置文件中(Spring为我们指定的位置)
- 测试类中进行测试
使用自定义类的进行切面的定义:
- 导入对应的织入包
- 导入相关的约束
- 编写我们希望实现的功能
- 在配置文件中,将我们编写的类以Bean的形式注册到指定的位置(Spring为我们指定的位置)
- 测试类中进行测试
使用注解的方式实现我们的切面定义:
- 导入对应的织入包
- 导入相关的约束
- 编写一个我们希望实现的功能
- 在方法的类中,指定的方法上面,使用相应的注解(我们前面说过,注解完全够达到xml文件的效果)
- 配置文件中我们开启对应的注解支持
- 测试类中进行测试
10、整合Mybatis
我们仔细回想一个Mybatis的整个编写过程中,哪里使用到了new关键字?
我们也说了IOC的核心理念就是控制反转,我们不再需要new,而是使用bean的方式,将我们的对象全部放入到spring容器中。那么这里的整合核心要素就是将那些new的,变成bean。
然后最终出现的现象就是,我们之前的mybatis-config.xml文件中配置的信息,都会转移到spring-dao.xml文件中,当然我们为了保留mybatis-config.xml是一个配置类,我们一般会留下别名和日志的设置。其他都迁移走。
不过整合的形式都是一样的,我们只需要记住顺序就行,实在不行,我们就粘贴复制。
空白的项目开始,多整合几次我相信你也就记住了。
11、事务
把一组事务当作一个业务来做,要么都成功,要么都失败。比如我去银行存钱,我们应该不希望我们的钱给进去了,但是程序出了问题,账户的余额没有添加的情况把!!!
事务的ACID原则:
- 原子性
- 一致性
- 隔离性
- 持久性
这是基本要点,一定要记住。像记CRUD一样的记住。
我们前面说过,Mybatis的配置里面是可以配置事务的,并且当Spring和Mybatis连用的时候,我们可以使用Spring的事务管理。同理,我们只需要按照对应的方式,注入Spring为我们提供的事务就能够完成事务的添加。