使用Maven方式来创建一个Spring项目,创建Spring项目和Servlet类似,总共分为以下3步:
创建一个普通的Maven项目注意点:项目名称和项目路径中不能有任何中文。
当 Java源代码根目录出现颜色以及resources资源目录出现标识图像时,说明该Maven项目已经初始化完毕。
在项目的 pom.xml 中添加 Spring 框架依赖(spring-context
依赖),xml 配置如下:
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.3.19version>
dependency>
dependencies>
在项目的 pom.xml 配置文件中添加spring-context
依赖后,需点击刷新键重新加载Maven项目,操作如下:
当在External Libra
目录下出现下述6个库,表明Spring-context
依赖添加成功。
疑问:我在pom.xml 中只添加了一个Spring-context
依赖,但为啥最终会有6个依赖呢?
解答:Spring-context
依赖的底层实现依赖于另外五个框架依赖,所以再添加Spring-context
依赖的同时也会把这另外5个也添加。
在Java源代码根目录java下创建一个启动类,该启动类包含main方法即可。
该启动类的功能是:为后面从Spring容器中读取Bean做准备。
测试Maven项目是否创建成功,可通过在main方法里写测试代码,根据代码能否成功运行来判断。
注:上述测试代码能够正常运行,说明Maven项目创建以及配置成功。
Bean对象就是 Java 语⾔中的⼀个普通对象,只是该对象能够被多次调用并使用。
操作流程:在resources资源目录下添加 Spring 配置⽂件spring-config.xml
,并添加下述配置:
<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 http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
beans>
在resources资源目录下添加配置文件示意图:
添加好配置文件后,再将Bean对象注册到 Spring 中就可以,具体操作是在 中添加如下配置:
注:id
指明Bean对象名称,class
指明Bean对象路径(包名 + 类名)。
<bean id="student" class="org.example.Student"></bean>
上述表示含义为:将Bean(org.example.Student)存到Spring 容器中,它的名称叫作student
。
Spring 上下文对象的获取可使用 ApplicationContex
,创建的时候需要配置 Spring 配置信息。
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
说明:ClassPathXmlApplicationContext
属于ApplicationContext
的⼦类,拥有ApplicationContext
的所有功能,是通过 xml 的配置来获取Spring容器中所有的 Bean对象。
注意:ClassPathXmlApplicationContext
里的参数configLocation
值应与Spring配置信息文件名相同。
获取指定Bean对象要求:getBean的参数值id
和class
要与指定Bean对象的id
和class
相对应。
Student student = context.getBean("student", Student.class);
获取指定Bean对象示意图:
student.sayHi();
读取Bean对象并使用的总操作流程代码:
import org.example.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
//1,获得Spring对象上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//2,获取指定的Bean对象
Student student = context.getBean("student", Student.class);
//3,使用Bean对象(非必须)
student.sayHi();
}
}
读取Bean对象并使用的总操作流程代码执行结果:
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
ApplicationContext
执行操作代码:
public static void main(String[] args) {
//1,获得Spring对象上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//2,获取指定的Bean对象
Student student = context.getBean("student", Student.class);
//3,使用Bean对象(非必须)
student.sayHi();
}
执行 ApplicationContext
打印结果:
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
BeanFactory
执行操作代码:
public static void main(String[] args) {
//1,获得Spring对象上下文
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
//2,获取指定的Bean对象
Student student = beanFactory.getBean("student", Student.class);
//3,使用Bean对象(非必须)
student.sayHi();
}
执行 BeanFactoryt
打印结果:
1,Student类(Bean对象)准备
public class Student {
public Student(){
System.out.println("do student init!");
}
public void sayHi(){
System.out.println("Hi student!");
}
}
2,Teacher类(Bean对象)准备
public class Teacher {
public Teacher(){
System.out.println("do teacher init!");
}
public void sayHi(){
System.out.println("Hi teacher!");
}
}
3,两种方式对比
执行 ApplicationContext
(无获取指定的Bean对象操作) 打印结果:
执行 BeanFactoryt
(有获取指定的Bean对象操作) 打印结果:
执行 BeanFactoryt
(有获取指定的Bean对象操作) 打印结果:
4,两种方式区别总结
ApplicationContext:该方式在获取Spring对象上下文时会对Spring容器中的所有Bean对象进行加载初始化。
方式特征:比较耗内存,一次性加载,后续Bean对象的读取不需进行加载初始化操作,效率高。
BeanFactory:该方式只有在调用getBean方法时才会进行加载初始化对应的Bean对象,而不是所有的Bean对象,属于懒加载。
方式特征:比较省内存,懒加载,只有当调用getBean时才会加载初始化对应的Bean对象,效率不高。
ApplicationContext
和BeanFactory
的联系:
ApplicationContext
和BeanFactory
都是接口,在使用时都是调用其的子类。
两种方式对比区别:从继承功能方面和性能方面这两个方面进行比较说明。
Student student = (Student) context.getBean("student");
该方式需经过两步操作,先获取到Bean对象,再经过强制类型转换为对应的类型,而强制类型转换容易出现空指针异常,不优雅。
如果Bean对象名称不存在,则会抛出NoSuchBeanDefinitionException
异常。
Student student = context.getBean(Student.class);
该方式存在缺陷,当有⼀个类型被重复注册到 spring-config.xml 中时,不可使用该方式,若使用则会抛出NoUniqueBeanDefinitionException
异常(非唯一的Bean异常)。
该方式推荐使用,既避免了强制类型转换带来的空指针异常问题,也避免了只根据类名获取Bean方式带来的非唯一的Bean异常问题。
Student student = context.getBean("student", Student.class);
解答:Spring 创建与使用的流程分为三大步,分别为Spring项目的创建,Bean对象的存储以及Bean对象的读取。具体流程为:
1)Spring项目的创建
2)存储Bean
3)读取Bean
1)ApplicationContext:在获取Spring对象上下文时会对Spring容器中的所有Bean对象进行加载初始化。
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
2)BeanFactory:只有在调用getBean方法时才会进行加载初始化对应的Bean对象,而不是所有的Bean对象。
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"))
3)两种方式区别:从继承功能方面和性能方面两个方面进行比较说明。
1)通过名称获取:有缺陷,需要进行强制性转换,而强制类型转换容易出现空指针异常。
Student student = (Student) context.getBean("student");
2)通过类名获取:有缺陷,当同类型的Bean对象有多个时,抛出NoUniqueBeanDefinitionException
异常(非唯一的Bean异常)。
Student student = context.getBean(Student.class);
3)通过名称+类名获取:推荐使用,规避了上述问题。
Student student = context.getBean("student", Student.class);