文章目录
- [一. Spring项目的创建](#一. Spring项目的创建)
-
- [1. 创建Maven项目](#1. 创建Maven项目)
- [2. 配置国内源](#2. 配置国内源)
- [3. 添加spring依赖](#3. 添加spring依赖)
- [4. 创建启动类](#4. 创建启动类)
- 二.储存或读取Bean对象
-
- [1. 添加spring配置文件](#1. 添加spring配置文件)
- [2. 创建Bean对象](#2. 创建Bean对象)
- [3. 读取Bean对象](#3. 读取Bean对象)
一. Spring项目的创建
1. 创建Maven项目
第一步,创建 Maven 项目,Spring 也是基于 Maven 的。
2. 配置国内源
由于国外源不稳定,可能让下面第二步引入 Spring 依赖会失败,所以这里先介绍如何一下配置国内镜像源。
现成的settings.xml
文件链接:gitee
如果你已经有了settings.xml
文件,但没有配置mirror
,配置内容如下:
java
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
如果你是在引入相关依赖失败后进行的国内源配置,就要去本地管理jar
包的目录将jar
包都进行删除,然后重新刷新下载依赖即可。
3. 添加spring依赖
第二步,在 Maven 项目中添加 Spring 的支持(spring-context, spring-beans)
在pom.xml
文件添加依赖项。
java
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
</dependencies>
刷新等待加载完成。
4. 创建启动类
第三步,创建启动类与 main
方法,用来做简单的测试
在 java
目录创建类,写代码即可,因为这里只演示怎么创建 Spring 项目和介绍 Spring 的简单使用,不会就上线发布,就不按照 Maven 的模板目录结构来搞了。
二.储存或读取Bean对象
1. 添加spring配置文件
右键resources
目录,新建一个spring-config.xml
配置文件。
配置内容如下:
java
<?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.xsd">
</beans>
2. 创建Bean对象
第一步,创建Bean
对象。
比如我们要注入一个Student
对象,就先的创建一个Student
类。
java
package com.tr.demo;
public class Student {
public void sayHi(String name) {
System.out.println("Hello!" + name );
}
}
然后将Bean
通过配置文件,注入到spring
中,即在spring
配置文件中通过以下语句注入。
java
<bean id="student" class="com.tr.demo.Student"></bean>
spring中对象的储存是通过键值对来存储的,其中key
为id
,value
为bean
,id
一般使用小驼峰命名。
3. 读取Bean对象
想要从 Spring 中将Bean
对象读取出来,先要得到 Spring 上下文对象,相当于得到了 Spring 容器。
再通过 spring 上下文对象提供的方法获取到需要使用的Bean
对象,最后就能使用Bean
对象了。
ApplicationContext
,也称为控制反转(IoC)容器,是 Spring 框架的核心。
实现类 | 描述 |
---|---|
ClassPathXmlApplicationContext(常用) | 加载类路径下的配置文件,要求配置文件必须在类路径下 |
FileSystemXmlApplicationContext | 可以加载磁盘任意路径下的配置文件(必须要有访问权限) |
AnnotationContigApplicationContext | 用于读取注解创建容器 |
java
import com.tr.demo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class APP {
public static void main(String[] args) {
// 1. 得到上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 2. 获取 bean 对象,这里根据 id 获取
Student student = (Student) context.getBean("student");
// 3. 使用 bean
student.sayHi("张三");
}
}
运行结果:
还可以使用 Bean 工厂(旧)来获取 Bean。
java
import com.tr.demo.Student;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class APP2 {
public static void main(String[] args) {
// 1. 得到 bean 工厂
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
// 2. 获取 bean 对象
Student student = (Student) factory.getBean("student");
// 3. 使用 bean
student.sayHi("李四");
}
}
但实际上并不推荐使用这种方式,算是过时代的方式了,因为旧时期需要考虑内存占用的问题,而现在内存资源没有这样的问题了。
运行结果:
此时我们可以发现,ApplicationContext
与BeanFactory
都可以从容器中获取Bean
,都提供了getBean
方法,最终的效果是一样的。
🍂那么, ApplicationContext
与 BeanFactory
有什么区别?
🎯相同点:
- 都是容器管理对象,都可以从容器中获取
Bean
,都提供了getBean
方法。
🎯不同点:
ApplicationContext
是BeanFactory
的子类,BeanFactory
只提供了基础访问Bean
对象的功能,而ApplicationContext
除了拥有BeanFactory
的全部功能,还有其他额外功能的实现,如国际化,资源访问以及事务传播方面等功能的支持。- 它们两加载
Bean
的机制也是不同的,BeanFactory
按需加载Bean
,属于懒汉方式,使用它程序启动快,在后期获取对象时会慢一些;而ApplicationContext
是饿汉方式,在创建时会将一次性将所有的Bean
都加载,这种方式启动慢,启动之后获取对象就非常快了。
这里验证一下他们两的加载机制:
我们在 com.tr.demo 目录下再添加一个Teacher
类,并完善Teacher
与Student
类的构造方法,这样当类被构造时会给出一些提示信息,在获取上下文或工厂时根据这些信息我们就可以知道Bean
是否会被构造。
java
package com.tr.demo;
public class Teacher {
public Teacher() {
System.out.println("Teacher 已加载!");
}
public void sayHi(String name) {
System.out.println("Hello!" + name );
}
}
package com.tr.demo;
public class Student {
public Student() {
System.out.println("Student 已加载!");
}
public void sayHi(String name) {
System.out.println("Hello!" + name );
}
}
java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class APP3 {
public static void main(String[] args) {
// 1. 得到上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
}
}
运行结果:
程序启动,ApplicationContext
创建时,会将所有的Bean
对象都构造,类似于饿汉的方式。
java
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class APP4 {
public static void main(String[] args) {
// 1. 得到 bean 工厂
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
}
}
运行结果:
程序启动,在BeanFactory
创建时,结果中没有如何输出,只要不去获取使用Bean
就不会去加载,类似于懒汉的方式。
getBean
方法,其实是有三种使用方式的,具体如下:
1️⃣方式1:根据Bean
的名字来获取
java
Student student = (Student) context.getBean("student");
这种方式返回的是一个Object
对象,需要我们去进行强制类型转换。
2️⃣方式2:根据Bean
类型获取
java
Student student = context.getBean(Student.class);
这种方式当beans
中只有一个类的实例没有问题,但是个有多个同类的实例,会有问题,即在 Spring 中注入多个同一个类的对象,就会报错。
我们来试一下,首先在 Spring 配置文件,注入多个Student
对象:
然后我们再通过这种方式来获取对象,运行结果如下:
抛出了一个NoUniqueBeanDefinitionException
异常,这表示注入的对象不是唯一的。
3️⃣方式3:根据名称 + 类型获取
java
Student student = context.getBean("student",Student.class);
相比方式1,更加健壮和优雅,也没有方式 2 中的问题
总结:
通篇下来涉及以下流程:
①创建 Spring 项目
②存储 Bean
- 先创建 Bean 对象
- 将 Bean 在 pring-config.xml 中进行配置
③取对象
- 得到 Spring 上下文,读取 Spring 配置文件
- 获取 Bean 对象
- 使用 Bean 对象(可选项)