写点什么

Spring 系列篇:Spring 容器基本使用及原理

用户头像
简爱W
关注
发布于: 2020 年 08 月 25 日
Spring系列篇:Spring容器基本使用及原理

环境


  1. jdk1.8

  2. idea

  3. maven-3.6.1

  4. spring-5.2.3.RELEASE

IOC 容器


IOC 容器是具有依赖注入功能的容器,负责对象的实例化、对象的初始化,对象和对象之间依赖关系配置、对象的销毁、对外提供对象的查找等操作,对象的整个生命周期都是由容器来控制。我们需要使用的对象都由 ioc 容器进行管理,不需要我们再去手动通过 new 的方式去创建对象,由 ioc 容器直接帮我们组装好,当我们需要使用的时候直接从 ioc 容器中直接获取就可以了。


那么 spring ioc 容器是如何知道需要管理哪些对象呢?


需要我们给 ioc 容器提供一个配置清单,这个配置支持 xml 格式java 注解的方式,在配置文件中列出需要让 ioc 容器管理的对象,以及可以指定让 ioc 容器如何构建这些对象,当 spring 容器启动的时候,就会去加载这个配置文件,然后将这些对象给组装好以供外部访问者使用。


这里所说的 IOC 容器也叫 spring 容器。


Bean 概念


由 spring 容器管理的对象统称为 Bean 对象。Bean 就是普通的 java 对象,和我们自己 new 的对象其实是一样的,只是这些对象是由 spring 去创建和管理的,我们需要在配置文件中告诉 spring 容器需要创建哪些 bean 对象,所以需要先在配置文件中定义好需要创建的 bean 对象,这些配置统称为 bean 定义配置元数据信息,spring 容器通过读取这些 bean 配置元数据信息来构建和组装我们需要的对象。


Spring 容器使用步骤


  1. 引入 spring 相关的 maven 配置

  2. 创建 bean 配置文件,比如 bean xml 配置文件

  3. 在 bean xml 文件中定义好需要 spring 容器管理的 bean 对象

  4. 创建 spring 容器,并给容器指定需要装载的 bean 配置文件,当 spring 容器启动之后,会加载这些配置文件,然后创建好配置文件中定义好的 bean 对象,将这些对象放在容器中以供使用

  5. 通过容器提供的方法获取容器中的对象,然后使用

Spring 容器对象


spring 内部提供了很多表示 spring 容器的接口和对象,我们来看看比较常见的几个容器接口和具体的实现类。


BeanFactory 接口


org.springframework.beans.factory.BeanFactory
复制代码

spring 容器中具有代表性的容器就是 BeanFactory 接口,这个是 spring 容器的顶层接口,提供了容器最基本的功能。


常用的几个方法


//按bean的id或者别名查找容器中的beanObject getBean(String name) throws BeansException
//这个是一个泛型方法,按照bean的id或者别名查找指定类型的bean,返回指定类型的bean对象<T> T getBean(String name, Class<T> requiredType) throws BeansException;
//返回容器中指定类型的bean对象<T> T getBean(Class<T> requiredType) throws BeansException;
//获取指定类型bean对象的获取器,这个方法比较特别,以后会专门来讲<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
复制代码


ApplicationContext 接口

org.springframework.context.ApplicationContext
复制代码

这个接口继承了 BeanFactory 接口,所以内部包含了 BeanFactory 所有的功能,并且在其上进行了扩展,增加了很多企业级功能,比如 AOP、国际化、事件支持等等。。

ClassPathXmlApplicationContext 类


org.springframework.context.support.ClassPathXmlApplicationContext
复制代码


这个类实现了 ApplicationContext 接口,注意一下这个类名称包含了 ClassPath Xml,说明这个容器类可以从 classpath 中加载 bean xml 配置文件,然后创建 xml 中配置的 bean 对象,一会后面的案例就会用到这个类。

AnnotationConfigApplicationContext 类


org.springframework.context.annotation.AnnotationConfigApplicationContext
复制代码


这个类也实现了 ApplicationContext 接口,注意其类名包含了 Annotation 和 config 两个单词,上面我们有说过,bean 的定义支持 xml 的方式和注解的方式,当我们使用注解的方式定义 bean 的时候,就需要用到这个容器来装载了,这个容器内部会解析注解来构建构建和管理需要的 bean。


注解的方式相对于 xml 方式更方便一些,也是我们比较推荐的方式,后面我们会大量使用这种方式,具体会详解。


案例


来个 helloworld 来详细看一下 spring 如何使用。


创建项目 spring-series


使用 idea 创建 maven 项目 spring-series,项目坐标:


<groupId>com.javacode2018</groupId><artifactId>spring-series</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version>
复制代码

spring-series 项目中创建一个子模块lesson-001,项目 maven 父子结构,如下图:


1581221060218

spring-series/pom.xml


<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>
<groupId>com.javacode2018</groupId> <artifactId>spring-series</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>lesson-001</module> </modules>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 配置maven编译的时候采用的编译器版本 --> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> <!-- 指定源代码是什么版本的,如果源码和这个版本不符将报错,maven中执行编译的时候会用到这个配置,默认是1.5,这个相当于javac命令后面的-source参数 --> <maven.compiler.source>1.8</maven.compiler.source> <!-- 该命令用于指定生成的class文件将保证和哪个版本的虚拟机进行兼容,maven中执行编译的时候会用到这个配置,默认是1.5,这个相当于javac命令后面的-target参数 --> <maven.compiler.target>1.8</maven.compiler.target> <spring.version>5.2.3.RELEASE</spring.version> </properties>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> </dependencies> </dependencyManagement></project>
复制代码

目前我们使用 spring 最新的版本5.2.3.RELEASE,需要引入 spring 提供的 3 个构件

spring-core、spring-context、spring-beans
复制代码


lesson-001\pom.xml


<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <parent>        <artifactId>spring-series</artifactId>        <groupId>com.javacode2018</groupId>        <version>1.0-SNAPSHOT</version>    </parent>    <modelVersion>4.0.0</modelVersion>
<artifactId>lesson-001</artifactId>
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </dependency> </dependencies>
</project>
复制代码


lesson-001 中创建 HelloWord 类

package com.javacode2018.lesson001.demo1;
/** * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!坚信用技术改变命运,让家人过上更体面的生活! */public class HelloWorld { public void say() { System.out.println("hello,欢迎和【路人甲Java】一起学spring!"); }}
复制代码

HelloWord 中我们创建了一个 say 方法,里面会输一段文字。


使用 spring 容器


下面我们通过 spring 容器来创建 HelloWord 对象,并从容器中获取这个对象,然后调用其 say 方法输出文字。


创建 bean xml 配置文件


新建一个文件,文件路径如下:


spring-series\lesson-001\src\main\resources\com\javacode2018\lesson001\demo1\bean.xml
复制代码


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">
<!-- 定义一个bean id:bean的唯一标识,可以通过这个标识从容器中获取这个bean对象 clss:这个bean的类型,完整类名称 --> <bean id="helloWorld" class="com.javacode2018.lesson001.demo1.HelloWorld"/>
</beans>
复制代码

上面就是 bean 的定义文件,每个 xml 中可以定义多个 bean 元素,通过 bean 元素定义需要 spring 容器管理的对象,bean 元素需指定 id 和 class 属性


  • id 表示这个 bean 的标识,在容器中需要唯一,可以通过这个 id 从容器中获取这个对象;

  • class 用来指定这个 bean 的完整类名

上面的配置文件中我们定义了一个helloWorld标识的HellWorld类型的 bean 对象。


创建测试类


创建一个 Client 类,如下:


package com.javacode2018.lesson001.demo1;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/** * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!坚信用技术改变命运,让家人过上更体面的生活! */public class Client {
public static void main(String[] args) { //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();
}}
复制代码


上面 main 方法中有容器的详细使用步骤,需要先创建容器对象,创建容器的对象的时候需要指定 bean xml 文件的位置,容器启动之后会加载这些配文件,然后将这些对象构建好。


代码中通过容器提供的 getBean 方法从容器中获取了 HellWorld 对象,第一个参数就是 xml 中 bean 的 id,第二个参数为 bean 对应的 Class 对象。


运行输出


hello,欢迎和【路人甲Java】一起学spring!
复制代码

总结


本文主要介绍了 spring 容器的概念、bean 的概念、常见的 spring 容器,以及 spring 容器的使用步骤;下一篇我们将详解 bean 的定义。


专注 Java 技术分享,交流 V:yuandengta522 (备注来源)可相互交换海量 Java 技术资料


用户头像

简爱W

关注

还未添加个人签名 2020.07.22 加入

还未添加个人简介

评论

发布
暂无评论
Spring系列篇:Spring容器基本使用及原理