目錄
創(chuàng)建 Spring 項(xiàng)目:
1.創(chuàng)建一個(gè) Maven 項(xiàng)目:
?2.添加 Spring 框架支持:
3.配置資源文件:
4.添加啟動(dòng)類:
Bean 對(duì)象的使用:
1.存儲(chǔ) Bean 對(duì)象:
1.1 創(chuàng)建 Bean:
1.2 存儲(chǔ) Bean 到容器內(nèi):
2.獲取 Bean 對(duì)象:
2.1 創(chuàng)建 Spring 上下文:
2.2 獲取指定 Bean 對(duì)象:
ApplicationContext 和 BeanFactory 的區(qū)別:
ApplicationContext:
BeanFactory:
總結(jié):
三種常用的 getBean :
根據(jù) id 獲?。?/p>
對(duì)象類型獲?。?/p>
id + 對(duì)象類型獲?。?/p>
總結(jié)
創(chuàng)建 Spring 項(xiàng)目:
? ? ? ? 創(chuàng)建一個(gè) Spring 項(xiàng)目分為四步:
- ?創(chuàng)建一個(gè)普通 Maven 項(xiàng)目;
- ?添加 Spring 框架支持;
- ?配置資源文件;
- ?添加啟動(dòng)類;
1.創(chuàng)建一個(gè) Maven 項(xiàng)目:
前提聲明:個(gè)人盡量使用 idea2021,因?yàn)?022版之后的相關(guān)插件是收費(fèi)的;
?2.添加 Spring 框架支持:
????????將這段配置依賴添加到 Spring 項(xiàng)目的 pom.xml 文件中:刷新下載到本地倉(cāng)庫(kù)
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.24</version>
</dependency>
</dependencies>
3.配置資源文件:
? ? ? ? 在 resources 包中創(chuàng)建一個(gè) xxx.xml 文件,再把 spring配置文件添加進(jìn)入即可:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
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">
<content:component-scan base-package="com.spring.demo"></content:component-scan>
</beans>
4.添加啟動(dòng)類:
? ? ? ? 在 java 文件下創(chuàng)建一個(gè)類,專門用來(lái)啟動(dòng)測(cè)試:
public class School {
public static void main(String[] args) {
}
}
Bean 對(duì)象的使用:
1.存儲(chǔ) Bean 對(duì)象:
? ? ? ? 原理:Spring 框架有 spring-context 來(lái)管理 spring 上下文,還有 spring-beans 來(lái)管理對(duì)象的模塊;
? ? ? ? 什么是 Bean對(duì)象?項(xiàng)目中重復(fù)使用的對(duì)象都可以視為 Bean 對(duì)象,存儲(chǔ) Bean 對(duì)象也就是把項(xiàng)目所需的對(duì)象放入 Spring 容器中;
1.1 創(chuàng)建 Bean:
? ? ? ? 現(xiàn)在創(chuàng)建了一個(gè)普通的 Student 類,其自帶一個(gè) sayHi() 方法,由于以后我還要頻繁使用這個(gè)類,那么就可以將其視為一個(gè) Bean:
public class Student {
public void sayHi() {
System.out.println("hi student");
}
}
1.2 存儲(chǔ) Bean 到容器內(nèi):
? ? ? ? 存儲(chǔ)bean也相當(dāng)于“聲明”的作用,先打開剛才在 resources包里創(chuàng)建的 spring-config.xml 配置文件:
存儲(chǔ) Bean 的格式:
<bean id="" class=""><bean>
如果 bean 在多級(jí)包內(nèi),class屬性設(shè)置時(shí)就要注意路徑;
現(xiàn)在將 Student 這個(gè)類作為 bean 添加進(jìn)去:注意路徑
<!-- 將Bean對(duì)象(com.spring.demo.com.spring.demo.Student)
存到 Spring容器中,它的 id 為 student-->
<bean id="student" class="com.spring.demo.Student"></bean>
2.獲取 Bean 對(duì)象:
? ? ? ? 獲取 bean 對(duì)象分為三步:
- 得到 Spring 上下文對(duì)象:因?yàn)?Bean 對(duì)象交給了 Spring 來(lái)管理,所以得先得到 Spring 才能有權(quán)限操作容器;
- 通過(guò) Spring 上下文獲取容器內(nèi)的 Bean 對(duì)象;
- 使用 Bean 對(duì)象;
2.1 創(chuàng)建 Spring 上下文:
? ? ? ? 這里需要了解兩個(gè)接口:ApplicationContext 和 BeanFactory;
? ? ? ? 語(yǔ)法:
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
BeanFactory beanFactory =
new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
2.2 獲取指定 Bean 對(duì)象:
? ? ? ? 這里借助?ApplicationContext 來(lái)演示:
public class School {
public static void main(String[] args) {
// 1.得到 Spring 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 2.獲取指定 Bean 對(duì)象
Student student = (Student) context.getBean("student");
// 3.使用 Bean 對(duì)象
student.sayHi();
}
}
至此 Spring 的創(chuàng)建、Bean 的存儲(chǔ)和獲取已經(jīng)做了基本介紹;
ApplicationContext 和 BeanFactory 的區(qū)別:
? ? ? ? 在上述代碼中再添加一個(gè) Teacher 類作為一個(gè)新的 Bean,添加到容器中:
public class Teacher {
public Teacher() {
System.out.println("do teacher init");
}
public void sayHi() {
System.out.println("hi teacher");
}
}
<bean id="student" class="com.spring.demo.Student"></bean>
<bean id="teacher" class="com.spring.demo.Teacher"></bean>
此時(shí)我們的容器中有兩個(gè) Bean:一個(gè)是Student、一個(gè)是Teacher;
????????分別使用 ApplicationContext 和 BeanFactory 來(lái)操作:都只嘗試獲取容器中 Student 這個(gè) Bean,來(lái)看看它們的效果有什么不同.
ApplicationContext:
? ? ? ? 原代碼不用變:?
public class School {
public static void main(String[] args) {
// 1.得到 Spring 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 2.獲取指定 Bean 對(duì)象
Student student = (Student) context.getBean("student");
// 3.使用 Bean 對(duì)象
student.sayHi();
}
}
BeanFactory:
? ? ? ? 創(chuàng)建一個(gè)新的啟動(dòng)類:School2,獲取 Spring 上下文和 ApplicationContext 不一樣,其他也不用變。
public class School2 {
public static void main(String[] args) {
// 1.使用 BeanFactory 來(lái)獲取 Spring 上下文
BeanFactory beanFactory =
new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
// 2. 從 Spring 容器中獲取 bean 對(duì)象
Student student = (Student) beanFactory.getBean("student");
student.sayHi();
}
}
?????????對(duì)比運(yùn)行結(jié)果,明明它們兩個(gè)都時(shí)獲取和使用?id 為 “student” 的 Bean 對(duì)象,ApplicationContext 對(duì)于上下文卻把 Teacher 也拿了出來(lái),BeanFactory 只拿到了 Student;
總結(jié):
相同點(diǎn):
- ApplicationContext 和 BeanFactory 都是獲取容器中Bean對(duì)象的;
不同點(diǎn):
- ?ApplicationContext 是一次性加載并初始化容器里的所有 Bean 對(duì)象(餓漢模式),而 BeanFactory 是需要哪個(gè)才去加載哪個(gè)(懶漢模式);
- ApplicationContext 其實(shí)是 BeanFactory 的子類,子類不僅繼承了父類的所有功能外,還擁有自己獨(dú)特的功能;而ClassPathXmlApplicationContext 又屬于 ApplicationContext的子類;
- BeanFactory 也是最早被設(shè)計(jì)出來(lái)的,設(shè)計(jì)之初由于機(jī)器硬件造價(jià)昂貴,就只加載需要的對(duì)象;而 ApplicationContext 是之后設(shè)計(jì)出來(lái)的,人們?yōu)榱吮M可能提高效率,就想到一次性加載出所有 Bean 對(duì)象;
三種常用的 getBean :
? ? ? ? getBean() 方法有很多重載,對(duì)比以下常用的三種:
- 根據(jù) id 獲取;
- 對(duì)象類型獲??;
- id,對(duì)象類型獲?。?/span>
根據(jù) id 獲?。?/h4>
<bean id="student" class="com.spring.demo.Student"></bean>
<bean id="teacher" class="com.spring.demo.Teacher"></bean>
// 2.獲取指定 Bean 對(duì)象
Student student = (Student) context.getBean("student");
Teacher teacher = (Teacher) context.getBean("teacher");
<bean id="student" class="com.spring.demo.Student"></bean>
<bean id="teacher" class="com.spring.demo.Teacher"></bean>
// 2.獲取指定 Bean 對(duì)象
Student student = (Student) context.getBean("student");
Teacher teacher = (Teacher) context.getBean("teacher");
這種方式顯然比較粗暴,不可取,存在強(qiáng)轉(zhuǎn);另外如果通過(guò)id獲取的對(duì)象為null,也會(huì)出現(xiàn)異常;
對(duì)象類型獲?。?/h4>
<bean id="student" class="com.spring.demo.Student"></bean>
<bean id="teacher" class="com.spring.demo.Teacher"></bean>
// 2.獲取指定 Bean 對(duì)象
Student student = context.getBean(Student.class);
Teacher teacher = context.getBean(Teacher.class);
<bean id="student" class="com.spring.demo.Student"></bean>
<bean id="teacher" class="com.spring.demo.Teacher"></bean>
// 2.獲取指定 Bean 對(duì)象
Student student = context.getBean(Student.class);
Teacher teacher = context.getBean(Teacher.class);
這種方式雖然不粗暴,但存在一個(gè)問題:
? ? ? ? 當(dāng)同一類型的 Bean 在容器中注冊(cè)了兩次,編譯器就會(huì)報(bào)?NoUniqueBeanDefinitionException 異常;
id + 對(duì)象類型獲?。?/h4>
????????這種方式安全性較高;
<bean id="student" class="com.spring.demo.Student"></bean>
<bean id="student2" class="com.spring.demo.Student"></bean>
<bean id="teacher" class="com.spring.demo.Teacher"></bean>
// 2.獲取指定 Bean 對(duì)象
Student student = context.getBean("student2",Student.class);
Teacher teacher = context.getBean("teacher",Teacher.class);
思考:
????????既然剛才提到了同一個(gè)類型可能在容器中注冊(cè)多次,雖然它們只是 id 不同,那它們指向的是否為同一塊空間呢?
? ? ? ? 代碼驗(yàn)證一下:
<bean id="student" class="com.spring.demo.Student"></bean>
<bean id="student2" class="com.spring.demo.Student"></bean>
<bean id="teacher" class="com.spring.demo.Teacher"></bean>
public class School {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Student student1 = context.getBean("student", Student.class);
Student student2 = context.getBean("student2", Student.class);
System.out.println(student1 == student2);
System.out.println(student1.equals(student2));
}
}
于是證明它們本身就是不同的對(duì)象的引用;
總結(jié):
Spring 項(xiàng)目的創(chuàng)建及 Bean 的基本使用流程:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-457786.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-457786.html
到了這里,關(guān)于從 Spring 的創(chuàng)建到 Bean 對(duì)象的存儲(chǔ)、讀取的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!