总体Spring还是有个大概的学习一次,但是很多东西仅仅是会用,这次就来从源码级别理解一下。
一、提前复习
1、回顾模块
- 咱Spring有如下模块
- 创建Spring项目
如果你不是使用Idea创建的话,其他方式创建需要导入需要的jar包。
① Spring 自身 JAR 包:spring-framework-4.0.0.RELEASE\libs 目录下- spring-beans-4.0.0.RELEASE.jar
- spring-context-4.0.0.RELEASE.jar
- spring-core-4.0.0.RELEASE.jar
- spring-expression-4.0.0.RELEASE.jar
2、回顾创建项目
上面我有的你留着,其他直接删除。
其他的自己可以找教程创建
- 输出HelloWorld
然后你就可以测试了
这个bean.xml文件是我们自己创建的hello.xml配置文件。
二、SpringIOC(重点)
(一)介绍与底层原理
1、IOC容器介绍
- Spring是一个容器,可以接管各个层次的Bean(action/domain/pojo/javabean),并且可以配置bean与bean之间的关系
- 在java代码里使用bean只需要 用ApplicationContext 的getBean(配置文件里bean的id)方法就可以了。
- 我自己的理解就是:控制反转就是把对象的创建,和对象的间的调用都交给Spring来管理,然后这样就降低了耦合度。
2、IOC底层原理
(1)通过工厂模式解耦
-
大白话就是:XML解析,工厂模式,反射
工厂模式不知道的回去补,反射不知道的回去补,XML解析不知道回去补 -
实现方法的调用看一下演变过程
- 咱看一下原始的实现方法的调用(耦合度高)
- 工厂模式调用(为了解决耦合度)
- 咱看一下原始的实现方法的调用(耦合度高)
(2)通过IOC来解耦
IOC就是利用我们的xml配置来进行解耦的
- 其实就是我们的xml接下得到我们的类型,把类型信息交给反射的forName方法得到此类,然后创建对象。
(3)IOC接口原理
IOC的思想需要基于我们的IOC容器来进行处理,它底层就是我们的对象工厂,这个接口就要关于我们的底层的对象工厂。通过两个接口实现IOC容器
- BeanFactory:IOC容器基本的实现方,开发中一般不适用,是Spring内部使用的接口。(它的一个特点:在加载配置文件的时候,不会去创建对象,而是要使用的时候才创建)
- ApplicationContext:它是BeanFactory的一个子接口,提供了更多更强大的功能的接口,这个就是提供给我们用户使用的(而它则加载就创建),它包括ApplicationContext主要实现类如下。
- 如果是用FileSystemXmlApplicationContext ,就要写里电脑的盘路径,写进去
- ClassPathXmlApplicationContext:它就是要写src里面的位置。
其实我自己理解发现,它这个ApplicationContext与BeanFactory把我自己写的配置文件,比如我写的hello.xml文件,它拿去后,它进行接管,它进行解析,获取类信息,需要的时候,创建就可以了,你不要再手动创建了。【这个要学完后面的注解开发就更清楚了】
(二)IOC容器-Bean管理XML文件的方式
其实bean就是我们写的XXX.java文件啊,还有什么其他数据源啊,等。
1、创建对象与set属性注入
(1)先看概念
- 什么是bean管理:其实就是Spring创建对象与对象属性注入。
- 对象的创建
- 属性管理
- 对象的创建
- bean管理的方式:基于xml配置文件方式实现与基于注解方式实现
(2)Bean管理
(2.1)创建对象
- 创建对象的管理
bean标签的属性- id标识:就是给你的类取一个唯一的标识。
- class:给你的类创建一个全路径。
- 了解一下的属性
- name:和id差不多的效果(name可以添加符号比如斜杠)
上面是默认的创建无参构造方法
- name:和id差不多的效果(name可以添加符号比如斜杠)
(2.2)属性的管理
-
DI:依赖注入,就是注入属性
常见面试题:DI与IOC的区别,如下回答
答:DI是IOC中的一种,表示依赖注入(或者说注入属性,当然属性,要在创建对象的基础上完成) -
演示
- 原始的方式
- 通过xml里面配置(可以通过有参方法注入与set方法注入)
这里的 name要对应就可以了
- 原始的方式
2、有参构造注入属性
(1)编写类
- 首先创建类并且一定要创建有参构造方法
(2)配置文件中注入
- 在Spring的配置文件中进行配置
首先再复习一下,我们的Spring的默认是使用的无参构造注入,这你使用有参构造注入理解
<bean id="book" class="cn.mldn.springtest.Book">
<constructor-arg name="A" value="12"></constructor-arg>
<constructor-arg name="B" value="China"></constructor-arg>
</bean>
3、P命名空间注入属性(可以简化基于xml的配置方式)
(1)配置约束
(2)编写类和配置
它的底层还是set注入
4、注入空值和特殊符号
- 先了解一下字面量:就是字面所表达的意思的量,看到就知道他的含义。就拿js的语法举例,5,一看就知道是个数字;“朋友”,一看就知道是个字符串;{a: 1},一看就知道是个对象。 英文是literal,翻译过来就是字面量。”
(1)注入null值
(2)注入特殊符号
5、注入属性
(1)外部bean
- 创建service和dao类,在service里面调用dao的update方法
- 原始方式很简单
- 原始方式很简单
- 在Spring内实现
这样也可以实现我们的方法的调用
(2)内部bean和级联赋值
- 多对一关系:部门和员工的典例之员工所属部门
- 级联赋值来实现dept
也可以通过如下,但是必须提供get方法
6、注入集合
(1)编写类
(2)进行配置
(3)在集合里面设置对象类型的值
(4)把注入的内容作为公共部分
- 首先引入一个名称空间
- 演示
- 使用公共部分
(三)bean相关配置
1、Spring中的FactoryBean
在spring两种类型的bean,一种是普通bean,另外一种是工厂bean
- 普通bean就是我们自己在配置文件中定义的,并且获得的类型也是此类型。
- 工厂bean返回的结果不一样,当然也可以选择一样
2、Bean的作用域
(1)先了解概念
- 概念就是:在Spring里面,设置创建bean实例是一个单实例还是多实例。【Spring默认情况下是bean是单实例对象】
- 单实例:其实就是总的来说就创建一个对象
- 多实例:就是每次需要使用的时候创建一个对象
(2)案例演示理解
- 默认情况下
- 演示多实例设置【在bean标签里面属性scope设置】
- scope=singleton 就是单实例
- scope=prototype就是多实例
- scope除了设置单实例与多实例外,scope=singleton时候,加载spring配置文件时候就会创建单实例对象
- 如果是scope=prototype时候,不是在加载spring配置文件的时候创建,而是在getBean的时候才会创建的,。
- 了解
- scope=request:会放到request域里面
- scope=session:会放在session里面
3、bean的生命周期
(1)概念
- bean的生命周期就是:对象创建到对象死亡的过程
- 过程分为如下
- 通过bean的无参构造方法创建bean
- 为bean里面的属性设置对应的值或者对其他bean的引用
- 调用bean的初始化的方法(需要进行配置)
- bean可以使用了{获取对象}
- 当容器被关闭时候,嗲用bean的销毁的方法(需要自己配置)
(2)演示
可以调用这个方法手动销毁,当然也可以如下
(3)后置处理器
-
过程分为如下
- 通过bean的无参构造方法创建bean
- 为bean里面的属性设置对应的值或者对其他bean的引用
- 把bean实例传递bean后置处理器的方法
- 调用bean的初始化的方法(需要进行配置)
- 把bean实例传递bean后置处理器的方法
- bean可以使用了{获取对象}
- 当容器被关闭时候,嗲用bean的销毁的方法(需要自己配置)
-
演示
- 创建类实现BeanPostProcess创建后置处理器
- 配置后置处理器
- 创建类实现BeanPostProcess创建后置处理器
4、bean的自动装配
上面我们在bean.xml里面手动配置的时候,都是进行手动的配置,接下来学习自动装配
(1)概念
- 自动装配:就是可以根据属性名称或者属性类型,spring会自动匹配的属性值进行注入。
(2)看一下演示
- 原始的配置
- 看自动装配
如果通过byType的话,不能定义多个同一个类型的bean
5、外部属性文件的配置
像如下方式虽然能配置,但是假设去数据库读取数据什么的,我们又要去修改,如果变化就要去修改,这样很麻烦,所以这里改变一下策略,在外部属性文件里面配置。
(1)原始的配置数据库
- 一般都是德鲁伊来进行连接
- 首先你得导入依赖:在lib里面导入依赖
我这里爆红的原因是因为我们没能引入依赖。
- 首先你得导入依赖:在lib里面导入依赖
(2)配置属性文件的格式
- 配置属性
- 引入文件并配置
(四)Bean管理注解创建
1、注解创建对象
(1)注解的位置与目的
- 注解可以作用在属性,方法,类上面。
- 要使用注解的目的:简化xml配置
(2)Spring针对bean管理中创建对象提供的注解
- @Component:
- @Service:
- @Controller:
- @Repository:
(3)基于注解实现对象创建
-
首先引入如下依赖
-
开启组件扫描
或者写
直接写上层路径 -
创建类并且添加注解
-
然后就可以创建对象了
2、组件扫描配置
像这总写,我们cn.mldn.springbean下面的配置全都都会被扫描的,这样不好
(1)关闭全扫描和指定扫描内容
- 关闭默认的filters方式
- 指定扫描具体内容,可以指定具体扫描哪些。
(2)指定不扫描
3、属性注入
下面都是根据类型的来注入的,不是针对普通数据
(1)@AutoWired
- 根据类型进行注入
(2)@Qualifier
- 根据属性的名称
如果你的UserDAO有多个实现类,那岂不是不能注入,所以我们来进行使用Qualifier
(3)@Resource
- 根据类型或者名称注入
- 根据类型注入
- 根据名称注入
这个注解它是javax包里面的哦,是spring官方建议的
- 根据类型注入
(4)@Value注解
- 它可以注入普通类型的属性,比如我们的String类型啊什么的
4、完全注解开发
上面方式中我们必须配置如下,但是我们可以实现完全注解开发