spring5系列(三) | 初识spring

简介: spring5系列(三) | 初识spring

经过了前面几篇文章的铺垫,从本章开始我们正式进入spring的学习。我们提到过spring的两大核心思想分别是IOC和AOP, 且spring和核心目的就是简化我们的开发和解耦合。 而简化我们开发的核心就是spring的工厂,spring提供了一个工厂,可以帮我我们完成对象的创建和实例化以及依赖注入的过程,那么我们本篇文章就来介绍下,spring工厂是如何帮我们管理类的。

一.spring的工厂和应用上下文

在基于spring的应用各种,你的应用对象生存于spring容器(container)中。spring容器负责创建对象,装配他们,配置值他们并管理他们的整个生命周期,从生存到死亡。

容器是spring框架的核心。spring容器使用DI管理 构成应用的组件,它会创建相互协作的组件之间的关联。 spring容器并不是只有一个。spring自带了多个容器实现。可以归为两种不同的类型。Bean工厂(org.springframework.beans.factory.BeanFactory 接口定义)是最简单的容器,提供基本的DI支持。应用上下文(org.springframework.context.ApplicationContext)接口定义,是基于BeanFactory构建(继承了BeanFactory),并提供了应用框架级别的服务,例如从属性文件解析文本信息及发布应用事件给感兴趣的事件监听者。一般我们经常使用应用上下文。

常见的应用上下文:

  • ClassPathXmlApplicationContext: 从类路径下读取spring配置文件,加载上下文定义,做对象的创建。用于非web应用
  • XmlWebApplicationContext: 在web应用使用,web项目的应用上下文
  • AnnotationConfigApplicationContext: 基于注解和java配置类的应用上下文
  • AnnotationConfigWebApplicationContext: 基于web项目,注解和java配置类的应用上下文。

这里提到的应用上下文,大家就可以把它们理解成就是spring的工厂(或者说容器),他们可以帮我们管理对象的整个生命周期。好了,接下来我们就来体验一下。

二. Hello World (spring)

2.1 代码演示

介绍完了spring的工厂,接下来我们就来体验一下,我们就来简单体验一下spring的用法。

我们先来进行环境搭建:我们采用如下环境配置 JDK 1.8, Maven 3.x, Spring 5.x

这个环境我们就不具体细说了,干过开发的应该都了解,那我我们首先引入spring的依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.14.RELEASE</version></dependeny>

然后我们就开始spring的使用 我们首先创建一个类: com.spring.User

packagecom.spring;
publicclassUser{
privateIntegerid;
privateStringname;
//get set方法省略}

这样就创建了一个简单单单的普通类,在不同spring的情况下,如果我们想要创建类的对象直接通过new的方式即可:

User user = new User();

而有了spring之后,对象的创建就交给了spring的工厂,那么该如何操作呢,spring 要想帮我们创建对象,我们必须得告诉他类在哪,同时创建好了之后,我们后续肯定是需要使用他,那么也需要定义一个名称,方便我们从spring工厂中获取,因为spring的工厂不可能只管理 一个对象。 所以spring最原始的方式的就是通过配置文件,在配置文件中定义好类的位置和名称,他就可以帮我们创建了。

我们在resources目录下,创建一个配置文件:applicationContext.xml ,配置内容如下

<?xmlversion="1.0" encoding="UTF-8" ?><beansxmlns="http://www.springframework.org/schema/beans"xmmls:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schemabeans/ http://www.springframework.org/schema/beans/spring-beans.xsd"><beanid="user"class="com.spring.User"/></beans>

我们在spring的配置文件中,添加了一个标签, 就代表这个类交给spring去管理,这个时候当我们启动spring的时候,spring就会帮我们创建这个类的对象,同时在使用的时候也可以直接从spring工厂中获取这个对象。 那么我们应该怎么来启动spring呢,其实也就是如果创建spring的工厂呢,这个就需要上篇文章我们提到的工厂了,而由于是非web项目,同时又是通过xml配置文件的方式启动工厂,所以我们需要使用的是XmlClassPathApplicationContext. 那么接下来我们通过程序演示如何创建工厂并获取对象。

publicclassSpringTest{
// 程序启动的入口publicstaticvoidmain(String[]args){
//指定spring配置文件并创建工厂ApplicationContextctx=newClassPathXmlApplicationContext("/applicationContext.xml");
// 根据配置文件中的id值获取对象  Useruser= (User)ctx.getBean("user");
  }  
}

通过上面的步骤,我们就可以获取到对应的类的对象了,也就省去了我们new的过程。 这样一看可能部分人又会觉得,这也没简单啊,相比我们自己new怎么反而更麻烦了呢,这大家要注意,这里只是给大家演示spring的简单用法和原理,我们真正的开发过程中是不会自己去用这样的方式创建工厂的。大家先明白原理。

2.2 注意细节

好了在说一下使用上面方式的一些细节:

  1. 配置文件的名称,一定要和resources目录下的文件名保持一致,否则读取不到配置信息就无法创建对象
  2. user对象的创建其实是在工厂创建的时候,也就是第一行代码执行完毕的时候就已经创建出来了。
  3. getBean() 括号里的参数一定要和配置文件中的id保持一致,获取的类型是Object,想要具体的对象类型需要进行强制类型转换。
  4. 配置文件中的class要写类的全路径,注意不要写错
  5. 配置文件中可以配置多个类,只需要写多个bean标签即可,同时注意id值必须唯一,不能重复。
  6. 除了id以外,也可以使用name代表类的别名,通过别名也可以获取类的对象
  7. id值可以省略,如果省略,会生成缺省id值:全类名#0,其中#0是一个计数形式,用来区分相同类型的其他bean.

2.3 spring工厂中的其他方法

刚刚我们使用的工厂中的getBean(String beanName) 方法,还有一些其他方法我也了解一下

名词解释: bean/component: spring工厂创建的对象

spring工厂的相关方法:

Person p = ctx.getBean("person", Person.class);

Person p = ctx.getBean(Person.class); // 配置文件中只能有一个Person类型的标签 String[] names = ctx.getBeanDefinitionNames(); // persion, person1. 所有bean标签的id

Stringn[] names = ctx.getBeanNamesForType(Person.class);// 根据类型获取名字,所有Person类型

boolean res = ctx.containsBeanDefinition("person");// 是否存在指定id对应标签 boolean res = ctx.containsBean("person");// 是否存在指定id对应标签

大家可以尝试一下。

三.浅析底层实现

上面我们通过一个简短的小程序验证了spring工厂装配一个bean的过程。大概总结为以下4步:

  1. 创建一个类
  2. 创建spring配置文件
  3. 在配置文件中通过标签指定类的id和路径
  4. 创建spring工厂,指定配置文件,通过工厂获取对象

步骤相对而言比较简单,那么我们来简单思考一下,这一切在spring的底层是如何实现的呢。其实主要应用的就是反射。通过读取配置文件我们就可以对配置文件进行解析。从而得到这个类的全类名,有了全类名,我们就可以通过反射获取对象了。大概步骤如下:

Classclazz=Class.forName("com.spring.User");
Objectuser=clazz.newInstance();

同时我们又指定了id, 我们可以简单理解有一个Map<String,Object> 的数据接口就相当于spring的工厂,id作用key,对象作为value, 这样通过id我们就可以得到对象了。

这里要注意,通过反射创建的对象是要调用类的构造方法的,默认是调用无参构造。当然私有的也是可以的,因为私有的构造方法也是可以通过反射创建出对象的。如果想尝试一下,可以直接在构造方法中打印一句话,在执行spring工厂创建的代码是,就会发现这句话能够打印出来。就验证上面的结论。同时也可以验证,对象到底是在工厂创建的时候创建还是在获取对象的时候创建的。

四. 总结

好了,本篇文章我们主要介绍了spring的初级用法,说实话比较简单,主要带大家回顾一下。这些内容我想学过spring的肯定都知道。没学过的,主要掌握bean标签的用法和工厂的创建即可。因为后续内容我们都会从这类进行展开。

参考资料:

Spring IN Action(第四版)  中国邮电出版社

孙帅spring详解:www.bilibili.com/video/BV185…


目录
相关文章
|
5月前
|
运维 Java 程序员
Spring5深入浅出篇:Spring切入点详解
该文档是关于Spring框架中切入点的详细解释。切入点是AOP(面向切面编程)的核心概念,用于定义通知(如日志、事务管理)应该附加到代码的哪些位置。文档主要介绍了切入点表达式的不同类型: 1. 方法切入点表达式:使用`execution()`定义匹配的方法,星号`*`代表任意返回值和方法名,`(..)`表示任意参数。 2. 类切入点:指定特定类以应用额外功能,可以精确到类中的所有方法,或者只包含特定包的类。 3. 包切入点表达式:适用于整个包或包及其子包内的所有类和方法。
|
5月前
|
Java 关系型数据库 MySQL
Spring5深入浅出篇:Spring中的FactoryBean对象
Spring5深入浅出篇:Spring中的FactoryBean对象
|
5月前
|
XML Java Shell
【深入浅出Spring原理及实战】「夯实基础系列」360全方位渗透和探究Spring的核心注解开发和实现指南(Spring5的常见的注解)
【深入浅出Spring原理及实战】「夯实基础系列」360全方位渗透和探究Spring的核心注解开发和实现指南(Spring5的常见的注解)
34 1
|
5月前
|
运维 Java 程序员
Spring5深入浅出篇:Spring动态代理详解
# Spring动态代理详解 本文探讨了Spring中的MethodBeforeAdvice和MethodInterceptor在动态代理中的应用和差异。MethodBeforeAdvice在方法执行前执行额外功能,而MethodInterceptor则可在方法执行前后或抛出异常时运行额外逻辑。MethodInterceptor还能影响原始方法的返回值。
|
2月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
5月前
|
设计模式 前端开发 Java
玩转Spring—Spring5新特性之Reactive响应式编程实战
玩转Spring—Spring5新特性之Reactive响应式编程实战
199 0
|
2月前
|
XML Java Maven
Spring5入门到实战------16、Spring5新功能 --整合日志框架(Log4j2)
这篇文章是Spring5框架的入门到实战教程,介绍了Spring5的新功能——整合日志框架Log4j2,包括Spring5对日志框架的通用封装、如何在项目中引入Log4j2、编写Log4j2的XML配置文件,并通过测试类展示了如何使用Log4j2进行日志记录。
Spring5入门到实战------16、Spring5新功能 --整合日志框架(Log4j2)
|
2月前
|
Java API Spring
Spring5入门到实战------1、Spring5框架概述、入门案例
这篇文章是Spring5框架的入门教程,概述了Spring框架的核心概念和特点,并通过一个创建普通Java类的案例,详细演示了从下载Spring核心Jar包、创建配置文件、编写测试代码到运行测试结果的完整流程,涵盖了Spring IOC容器的使用和依赖注入的基本用法。
|
5月前
|
设计模式 运维 Java
Spring5深入浅出篇:Spring中静态代理与动态代理
Spring框架中的代理模式分为静态代理和动态代理。在JavaEE分层开发中,Service层最为重要,包含核心业务逻辑和额外功能。静态代理通过手动创建代理类来增加原始类的额外功能,但当代理类数量多时管理不便且不易于维护。动态代理则解决了这一问题,通过Spring的AOP(面向切面编程)实现,无需手动创建代理类,只需定义切点和增强(额外功能),在运行时动态生成代理对象,提高了代码的灵活性和可维护性。动态代理主要利用了JVM的字节码技术,在运行过程中创建代理类,执行完毕后随着虚拟机的结束而销毁,不会产生持久化的代理类。
|
5月前
|
Java 数据库连接 Spring
Spring5深入浅出篇:Spring配置⽂件参数化
该文档介绍了Spring配置文件参数化的概念和步骤。目的是将经常需要修改的配置,如数据库连接参数,从主配置文件中分离到一个单独的`.properties`文件,以便于管理和维护。步骤包括创建小型配置文件(如`db.properties`),在`applicationContext.xml`中引入该文件,并使用`${key}`语法在Spring配置文件中引用这些参数。最终通过测试验证配置文件参数化的成功。