目录
5.ClassPathXmlApplicationContext类
6.AnnotationConfigApplicationContext类
一.spring介绍
1.什么是spring
spring 是一个简化 java 企业级开发的一个框架,内部包含了很多技术,比如:控制反转【IOC】 & 依赖注入【DI】、面向切面编程【AOP】、spring 事务管理、通过 spring 集成其他框架、 springmvc 、 sprigboot 、 springcloud等等,
2.spring容器
spring 容器的概念,容器这个名字起的相当好,容器可以放很多东西,我们的程序启动的时候会创建spring 容器,会给 spring 容器一个清单,清单中列出了需要创建的对象以及对象依赖关系, spring 容器会创建和组装好清单中的对象,然后将这些对象存放在 spring 容器中,当程序中需要使用的时候,可以到容器中查找获取,然后直接使用。
3.IOC:控制反转
使用者之前使用 B 对象的时候都需要自己去创建和组装,而现在这些创建和组装都交给 spring 容器去给完成了,使用者只需要去spring 容器中查找需要使用的对象就可以了;这个过程中 B 对象的创建和组装过程被反转了,之前是使用者自己主动去控制的,现在交给spring 容器去创建和组装了,对象的构建过程被反转了,所以叫做控制反转;IOC 是是面相对象编程中的一种设计原则,主要是为了降低系统代码的耦合度,让系统利于维护和扩展。
4.DI:依赖注入
依赖注入是 spring 容器中创建对象时给其设置依赖对象的方式,比如给 spring 一个清单,清单中列出了需要创建B 对象以及其他的一些对象(可能包含了 B 类型中需要依赖对象),此时 spring 在创建 B 对象的时候,会看B 对象需要依赖于哪些对象,然后去查找一下清单中有没有包含这些被依赖的对象,如果有就去将其创建好,然后将其传递给B 对象;可能 B 需要依赖于很多对象, B 创建之前完全不需要知道其他对象是否存在或者其他对象在哪里以及被他们是如何创建,而spring 容器会将 B 依赖对象主动创建好并将其注入到B 中去,比如 spring 容器创建 B 的时候,发现 B 需要依赖于 A ,那么 spring 容器在清单中找到 A 的定义并将其创建好之后,注入到B 对象中。
总结
1. IOC
控制反转,是一种设计理念,将对象创建和组装的主动控制权利交给了
spring
容器去做,控制 的动作被反转了,降低了系统的耦合度,利于系统维护和扩展,主要就是指需要使用的对象的组装
控制权被反转了,之前是自己要做的,现在交给
spring
容器做了
。
2. DI
依赖注入,表示
spring
容器中创建对象时给其设置依赖对象的方式,通过某些注入方式可以让系 统更灵活,比如自动注入等可以让系统变的很灵活,这个后面的文章会细说。
3. spring
容器:主要负责容器中对象的创建、组装、对象查找、对象生命周期的管理等等操作。
二.Spring容器基本使用及原理
1.Bean概念
由 spring 容器管理的对象统称为 Bean 对象。 Bean 就是普通的 java 对象,和我们自己 new 的对象其实是一 样的,只是这些对象是由spring 去创建和管理的,我们需要在配置文件中告诉 spring 容器需要创建哪些 bean对象,所以需要先在配置文件中定义好需要创建的 bean 对象,这些配置统称为 bean 定义配置元数据信息,spring 容器通过读取这些 bean 配置元数据信息来构建和组装我们需要的对象。
2.Spring容器使用步骤
1. 引入 spring 相关的 maven 配置2. 创建 bean 配置文件,比如 bean xml 配置文件3. 在 bean xml 文件中定义好需要 spring 容器管理的 bean 对象4. 创建 spring 容器,并给容器指定需要装载的 bean 配置文件,当 spring 容器启动之后,会加载这些配置文件,然后创建好配置文件中定义好的 bean 对象,将这些对象放在容器中以供使用5. 通过容器提供的方法获取容器中的对象,然后使用
3.BeanFactory接口
org.springframework.beans.factory.BeanFactory
spring 容器中具有代表性的容器就是 BeanFactory 接口,这个是 spring 容器的顶层接口,提供了容器最基本的功能。
4.ApplicationContext接口
org.springframework.context.ApplicationContext
这个接口继承了 BeanFactory 接口,所以内部包含了 BeanFactory 所有的功能,并且在其上进行了扩展,增加了很多企业级功能,比如 AOP 、国际化、事件支持等等。。
5.ClassPathXmlApplicationContext类
这个类实现了 ApplicationContext 接口,注意一下这个类名称包含了 ClassPath Xml ,说明这个容器类可以从 classpath 中加载 bean xml 配置文件,然后创建 xml 中配置的 bean 对象
6.AnnotationConfigApplicationContext类
这个类也实现了 ApplicationContext 接口,注意其类名包含了 Annotation 和 config 两个单词,上面我们有说过, bean 的定义支持 xml 的方式和注解的方式,当我们使用注解的方式定义 bean 的时候,就需要用到这个容器来装载了,这个容器内部会解析注解来构建构建和管理需要的 bean 。注解的方式相对于 xml方式更方便一些,也是我们比较推荐的方式。
案例
1. 创建bean xml配置文件
<?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
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"
>
<import
resource
=
"
引入其他
bean xml
配置文件
"
/>
<bean
id
=
"bean
标识
"
class
=
"
完整类型名称
"
/>
<alias
name
=
"bean
标识
"
alias
=
"
别名
"
/>
</beans>
2.测试
//1.bean
配置文件位置
String
beanXml
=
"classpath:/com/javacode2018/lesson001/demo1/beans.xml"
;
//2.
创建
ClassPathXmlApplicationContext
容器,给容器指定需要加载的
bean
配置文件
ClassPathXmlApplicationContext context
=
new
ClassPathXmlApplicationContext
(
beanXml
);
//3.
从容器中获取需要的
bean
HelloWorld helloWorld
=
context
.
getBean
(
"helloWorld"
,
HelloWorld
.
class
);
//4.
使用对象
helloWorld
.
say
();
代码中通过容器提供的 getBean 方法从容器中获取了 HellWorld 对象,第一个参数就是 xml 中 bean 的 id ,第二个参数为 bean 对应的 Class 对象。
3.获取bean的名称和别名的方法
getAliases
:通过
bean
名称获取这个
bean
的所有别名
getBeanDefinitionNames
:返回
spring
容器中定义的所有
bean
的名称
4.id和name都未指定
当
id
和
name
都未指定的时候,
bean
的名称和别名又是什么呢?
此时由
spring
自动生成,
bean名称为:【
bean
的
class
的完整类名
#
编号
】
上面的编号是从
0
开始的,同种类型的没有指定名称的依次递增。
5.alias元素
<alias
name
=
"
需要定义别名的
bean"
alias
=
"
别名
"
/>
6.import元素
<
import
resource
=
"
其他配置文件的位置
"
/>
三.容器创建bean实例有多少种?
1. 通过反射调用构造方法创建bean对象
调用类的构造方法获取对应的 bean 实例,是使用最多的方式,这种方式只需要在 xml bean 元素中指定class 属性, spring 容器内部会自动调用该类型的构造方法来创建 bean 对象,将其放在容器中以供使用。
<bean
id
=
"bean
名称
"
name
=
"bean
名称或者别名
"
class
=
"bean
的完整类型名称
"
>
<constructor-arg
index
=
"0"
value
=
"bean
的值
"
ref
=
"
引用的
bean
名称
"
/>
<constructor-arg
index
=
"1"
value
=
"bean
的值
"
ref
=
"
引用的
bean
名称
"
/>
<constructor-arg
index
=
"2"
value
=
"bean
的值
"
ref
=
"
引用的
bean
名称
"
/>
....
<constructor-arg
index
=
"n"
value
=
"bean
的值
"
ref
=
"
引用的
bean
名称
"
/>
</bean>、
注:【index属性可以不加】
constructor-arg 用于指定构造方法参数的值index :构造方法中参数的位置,从 0 开始,依次递增value :指定参数的值ref :当插入的值为容器内其他 bean 的时候,这个值为容器中对应 bean 的名称
2. 通过静态工厂方法创建bean对象
3. 通过实例工厂方法创建bean对象
前面我们学过了 BeanFactory 接口, BeanFactory 是 spring 容器的顶层接口,而这里要说的是FactoryBean ,也是一个接口,这两个接口很容易搞混淆, FactoryBean 可以让 spring 容器通过这个接口的实现来创建我们需要的 bean 对象。
4. 通过FactoryBean创建bean对象
前面我们学过了 BeanFactory 接口, BeanFactory 是 spring 容器的顶层接口,而这里要说的是FactoryBean ,也是一个接口,这两个接口很容易搞混淆, FactoryBean 可以让 spring 容器通过这个接口的实现来创建我们需要的 bean 对象。
package com.zcc.zhangchunchao.pojo;
import org.springframework.lang.Nullable;
public interface FactoryBean<T> {
/*** 返回创建好的对象 */
@Nullable
T getObject() throws Exception;
/*** 返回需要创建的对象的类型 */
@Nullable
Class<?> getObjectType();
/** * bean是否是单例的 **/
default boolean isSingleton() {
return true;
}
}