??BeanDefinition
是Spring
中一個非常重要的概念,它包含了Spring
容器用于創(chuàng)建、配置Bean
所需的所有信息。理解BeanDefinition
可以幫助我們深入掌握Spring
的內(nèi)部工作機(jī)制。
1. 探索BeanDefinition
首先,讓我們來對 BeanDefinition
有一個整體的認(rèn)識。
1.1 官方文檔對BeanDefinition的解讀
??對于理解Spring
框架的概念和組件,Spring
的官方文檔是一個非常重要的資源。關(guān)于BeanDefinition
,官方文檔大意如下:
??BeanDefinition
包含了大量的配置信息,這些信息可以指導(dǎo)Spring
如何創(chuàng)建Bean
,包括Bean
的構(gòu)造函數(shù)參數(shù),屬性值,初始化方法,靜態(tài)工廠方法名稱等等。此外,子BeanDefinition
還可以從父BeanDefinition
中繼承配置信息,同時也可以覆蓋或添加新的配置信息。這種設(shè)計模式有效減少了冗余的配置信息,使配置更為簡潔。
接下來,讓我們通過一個具體的例子來更好地理解BeanDefinition
。
考慮一個簡單的Java
類,Person
:
public class Person {
private String name;
private int age;
public Person() {}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getters and setters
}
我們可以用XML
配置或者Java
配置的方式來定義一個Person
類型的Bean
,同時這個Bean
的配置信息會被封裝在BeanDefinition
中。
在XML
配置中,一個Person Bean
的定義可能如下:
<bean id="person" class="com.example.Person">
<constructor-arg name="name" value="John"/>
<constructor-arg name="age" value="25"/>
</bean>
在這里,BeanDefinition
的信息包括了class
屬性(全限定類名)以及構(gòu)造函數(shù)參數(shù)的名稱和值。
在Java
配置中,我們可以這樣定義一個Person Bean
:
@Configuration
public class AppConfig {
@Bean
public Person person() {
return new Person("John", 25);
}
}
??在這個例子中,BeanDefinition
的信息包括class
屬性(全限定類名)以及構(gòu)造函數(shù)參數(shù)。我們可以通過BeanDefinition
的getBeanClassName()
方法獲取到這個全限定類名。
1.2 BeanDefinition關(guān)鍵方法剖析
BeanDefinition
接口定義了Bean
的所有元信息,主要包含以下方法:
-
get/setBeanClassName() - 獲取/設(shè)置
Bean
的類名 -
get/setScope() - 獲取/設(shè)置
Bean
的作用域 - isSingleton() / isPrototype() - 判斷是否單例/原型作用域
- get/setInitMethodName() - 獲取/設(shè)置初始化方法名
- get/setDestroyMethodName() - 獲取/設(shè)置銷毀方法名
- get/setLazyInit() - 獲取/設(shè)置是否延遲初始化
-
get/setDependsOn() - 獲取/設(shè)置依賴的
Bean
- get/setPropertyValues() - 獲取/設(shè)置屬性值
- get/setAutowireCandidate() - 獲取/設(shè)置是否可以自動裝配
-
get/setPrimary() - 獲取/設(shè)置是否首選的自動裝配
Bean
??由于BeanDefinition
源碼篇幅較長,這里就不全部貼上來,大家可以自行查看。BeanDefinition
還實現(xiàn)了AttributeAccessor
接口,可以通過該接口添加自定義元數(shù)據(jù),后面小節(jié)會舉例AttributeAccessor
的使用。
??從上面可以看到,BeanDefinition
是 Spring
框架中用來描述 Bean
的元數(shù)據(jù)對象,這個元數(shù)據(jù)包含了關(guān)于 Bean
的一些基本信息,包括以下幾個方面:
-
Bean 的類信息: 這是
Bean
的全限定類名,即這個Bean
實例化后的具體類型。 -
Bean 的屬性信息: 包括了如
Bean
的作用域(是單例還是原型)、是否為主要的Bean
(primary
)、描述信息等。 -
Bean 的行為特性: 例如
Bean
是否支持延遲加載,是否可以作為自動裝配的候選者,以及Bean
的初始化和銷毀方法等。 -
Bean 與其他 Bean 的關(guān)系: 比如說這個
Bean
所依賴的其他Bean
,以及這個Bean
是否有父Bean
。 -
Bean 的配置信息: 這包括了
Bean
的構(gòu)造器參數(shù),以及屬性值等。
1.3 BeanDefinition部分方法的實際運用
??接下來用一個詳細(xì)的代碼示例來說明BeanDefinition
接口中各個方法的使用,并結(jié)合實際的代碼示例說明這些方法的實際含義。下面,我會針對BeanDefinition
的幾個重要方面提供代碼示例。
全部代碼如下:
首先,這是我們的Java
配置類以及Person
類的定義:
package com.example.demo.configuration;
import com.example.demo.bean.Person;
import org.springframework.context.annotation.*;
@Configuration
public class AppConfig {
@Bean(initMethod = "init", destroyMethod = "cleanup")
@Scope("singleton")
@Lazy
@Primary
@Description("A bean for person")
public Person person() {
return new Person("John", 25);
}
}
package com.example.demo.bean;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getters and setters
public void init() {
System.out.println("Initializing Person bean");
}
public void cleanup() {
System.out.println("Cleaning up Person bean");
}
}
下面是如何通過BeanDefinition
獲取到各個屬性:
package com.example.demo;
import com.example.demo.configuration.AppConfig;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.Arrays;
public class DemoApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
String personBeanName = "person";
BeanDefinition personBeanDefinition = context.getBeanFactory().getBeanDefinition(personBeanName);
// 獲取Bean的類信息
System.out.println("Bean Class Name: " + context.getBean(personBeanName).getClass().getName());
// 獲取Bean的屬性
System.out.println("Scope: " + personBeanDefinition.getScope());
System.out.println("Is primary: " + personBeanDefinition.isPrimary());
System.out.println("Description: " + personBeanDefinition.getDescription());
// 獲取Bean的行為特征
System.out.println("Is lazy init: " + personBeanDefinition.isLazyInit());
System.out.println("Init method: " + personBeanDefinition.getInitMethodName());
System.out.println("Destroy method: " + personBeanDefinition.getDestroyMethodName());
// 獲取Bean的關(guān)系
System.out.println("Parent bean name: " + personBeanDefinition.getParentName());
System.out.println("Depends on: " + Arrays.toString(personBeanDefinition.getDependsOn()));
// 獲取Bean的配置屬性
System.out.println("Constructor argument values: " + personBeanDefinition.getConstructorArgumentValues());
System.out.println("Property values: " + personBeanDefinition.getPropertyValues());
}
}
運行結(jié)果:
??這個例子包含了BeanDefinition
的大部分方法,展示了它們的作用。請注意,在這個例子中,一些方法如getDependsOn()
、getParentName()
、getConstructorArgumentValues()
、getPropertyValues()
的返回結(jié)果可能不會顯示出任何實質(zhì)內(nèi)容,因為我們的person Bean
并沒有設(shè)置這些值。如果在實際應(yīng)用中設(shè)置了這些值,那么這些方法將返回相應(yīng)的結(jié)果。
1.4 BeanDefinition深層信息結(jié)構(gòu)梳理
在 Spring
中,BeanDefinition
包含了以下主要信息:
-
Class:這是全限定類名,
Spring
使用這個信息通過反射創(chuàng)建Bean
實例。例如,com.example.demo.bean.Book
,當(dāng)Spring
需要創(chuàng)建Book bean
的實例時,它將根據(jù)這個類名通過反射創(chuàng)建Book
類的實例。 -
Name:這是
Bean
的名稱。在應(yīng)用程序中,我們通常使用這個名稱來獲取Bean
的實例。例如,我們可能有一個名稱為"bookService"
的Bean
,我們可以通過context.getBean("bookService")
來獲取這個Bean
的實例。 -
Scope:這定義了
Bean
的作用域,例如singleton
或prototype
。如果scope
是singleton
,那么Spring
容器將只創(chuàng)建一個Bean
實例并在每次請求時返回這個實例。如果scope
是prototype
,那么每次請求Bean
時,Spring
容器都將創(chuàng)建一個新的Bean
實例。 -
Constructor arguments:這是用于實例化
Bean
的構(gòu)造函數(shù)參數(shù)。例如,如果我們有一個Book
類,它的構(gòu)造函數(shù)需要一個String
類型的參數(shù)title
,那么我們可以在BeanDefinition
中設(shè)置constructor arguments
來提供這個參數(shù)。 -
Properties:這些是需要注入到
Bean
的屬性值。例如,我們可能有一個Book
類,它有一個title
屬性,我們可以在BeanDefinition
中設(shè)置properties
來提供這個屬性的值。這些值也可以通過<property>
標(biāo)簽或@Value
注解在配置文件或類中注入。 -
Autowiring Mode:這是自動裝配的模式。如果設(shè)置為
byType
,那么Spring
容器將自動裝配Bean
的屬性,它將查找容器中與屬性類型相匹配的Bean
并注入。如果設(shè)置為byName
,那么容器將查找容器中名稱與屬性名相匹配的Bean
并注入。還有一個選項是constructor
,它指的是通過Bean
構(gòu)造函數(shù)的參數(shù)類型來自動裝配依賴。 -
Lazy Initialization:如果設(shè)置為
true
,Bean
將在首次請求時創(chuàng)建,而不是在應(yīng)用啟動時。這可以提高應(yīng)用的啟動速度,但可能會在首次請求Bean
時引入一些延遲。 -
Initialization Method and Destroy Method:這些是
Bean
的初始化和銷毀方法。例如,我們可能有一個BookService
類,它有一個名為init
的初始化方法和一個名為cleanup
的銷毀方法,我們可以在BeanDefinition
中設(shè)置這兩個方法,那么Spring
容器將在創(chuàng)建Bean
后調(diào)用init
方法,而在銷毀Bean
之前調(diào)用cleanup
方法。 -
Dependency beans:這些是
Bean
的依賴關(guān)系。例如,我們可能有一個BookService Bean
,它依賴于一個BookRepository Bean
,那么我們可以在BookService
的BeanDefinition
中設(shè)置dependency beans
為"bookRepository"
,那么在創(chuàng)建BookService Bean
之前,Spring
容器將首先創(chuàng)建BookRepository Bean
。
??以上就是 BeanDefinition
中主要包含的信息,這些信息將會告訴 Spring
容器如何創(chuàng)建和配置 Bean
。不同的 BeanDefinition
實現(xiàn)可能會有更多的配置信息。例如,RootBeanDefinition
、ChildBeanDefinition
、GenericBeanDefinition
等都是 BeanDefinition
接口的具體實現(xiàn)類,它們可能包含更多的配置選項。
2. BeanDefinition構(gòu)造體系解析
??讓我們首先明確BeanDefinition
的角色。BeanDefinition
是Spring
中的核心組件,它定義了bean
的配置信息,包括類名、作用域、構(gòu)造器參數(shù)、屬性值等。下面我們來看看BeanDefinition
在Spring
中的設(shè)計是如何的。
通過IDEA
我們可以得到如下的繼承關(guān)系圖:
雖然有許多接口、抽象類和擴(kuò)展,我們只需要關(guān)注其中的關(guān)鍵部分。
2.1 BeanDefinition的類型及其應(yīng)用
在Spring
中,一個bean
的配置信息就是由BeanDefinition
對象來保存的。根據(jù)bean
配置的不同來源和方式,BeanDefinition
又被分為很多種類型,我們選取其中幾種講解一下
-
RootBeanDefinition:當(dāng)我們在
XML
配置文件中定義一個bean
時,Spring
會為這個bean
創(chuàng)建一個RootBeanDefinition
對象,這個對象包含了所有用于創(chuàng)建bean
的信息,如bean
的類名、屬性值等。例如:
<bean id="exampleBean" class="com.example.ExampleBean">
<property name="stringProperty" value="stringValue"/>
</bean>
??這段XML
配置中定義了一個名為"exampleBean"
的bean
,它的類是"com.example.ExampleBean"
,并且有一個名為"stringProperty"
的屬性值是"stringValue"
。當(dāng)Spring
讀取這段配置時,會創(chuàng)建一個RootBeanDefinition
對象來保存這個bean的所有配置信息。
??總結(jié):在XML
文件中定義一個bean
時,Spring
就會創(chuàng)建一個RootBeanDefinition
實例,這個實例會保存所有的配置信息,比如類名、屬性值等。
-
ChildBeanDefinition:當(dāng)我們需要讓一個
bean
繼承另一個bean
的配置時,可以使用ChildBeanDefinition
。例如:
<bean id="parentBean" class="com.example.ParentBean">
<property name="stringProperty" value="stringValue"/>
</bean>
<bean id="childBean" parent="parentBean">
<property name="anotherStringProperty" value="anotherStringValue"/>
</bean>
??這段XML
配置中,"childBean"
繼承了"parentBean"
的所有配置,同時還添加了一個新的屬性"anotherStringProperty"
。當(dāng)Spring
讀取這段配置時,會首先為"parentBean"
創(chuàng)建一個RootBeanDefinition
對象,然后為"childBean"
創(chuàng)建一個ChildBeanDefinition
對象,這個對象會引用"parentBean"
的BeanDefinition
。
??總結(jié):如果有一個bean
,并且想創(chuàng)建一個新的bean
,這個新的bean
需要繼承原有bean
的所有配置,但又要添加或修改一些配置信息,Spring
就會創(chuàng)建一個ChildBeanDefinition
實例。
-
GenericBeanDefinition:這是一種通用的
BeanDefinition
,可以根據(jù)需要轉(zhuǎn)化為RootBeanDefinition
或者ChildBeanDefinition
。例如,在一個配置類中使用@Bean
注解定義了一個bean
:
@Configuration
public class AppConfig {
@Bean
public MyComponent myComponent() {
return new MyComponent();
}
}
??在這段代碼中,我們定義了一個名為"myComponent"
的bean
,它的類是"MyComponent"
。當(dāng)Spring
解析這個配置類時,會為myComponent()
方法創(chuàng)建一個GenericBeanDefinition
對象。這個GenericBeanDefinition
對象會保存方法的名字(這也是bean
的名字)、返回類型,以及任何需要的構(gòu)造函數(shù)參數(shù)或?qū)傩?。在這個例子中,我們沒有定義任何參數(shù)或?qū)傩?,所?code>GenericBeanDefinition對象只包含了基本的信息。這個GenericBeanDefinition
對象之后可以被Spring
容器用于生成bean
的實例。
??總結(jié):在Java
配置類中使用@Bean
注解定義一個bean
時,Spring
就會創(chuàng)建一個GenericBeanDefinition
實例。
-
AnnotatedBeanDefinition:當(dāng)我們在代碼中使用注解(如
@Component
,@Service
,@Repository
等)來定義bean
時,Spring
會創(chuàng)建一個AnnotatedBeanDefinition
接口的實例。例如:
@Component("myComponent")
public class MyComponent {
// some fields and methods
}
??在這段代碼中,我們定義了一個名為"myComponent"
的bean
,它的類是"MyComponent"
,并且這個類上有一個@Component
注解。當(dāng)Spring
解析這個類時,會創(chuàng)建一個AnnotatedBeanDefinition
對象。這個AnnotatedBeanDefinition
對象會保存類名(這也是bean
的名字)、類的類型,以及類上的所有注解信息。在這個例子中,AnnotatedBeanDefinition
實例會包含@Component
注解及其所有元數(shù)據(jù)。這個AnnotatedBeanDefinition
實例之后可以被Spring
容器用于生成bean
的實例,同時Spring
還可以使用存儲在AnnotatedBeanDefinition
中的注解信息來進(jìn)行進(jìn)一步的處理,如AOP
代理、事務(wù)管理等。
??總結(jié):在類上使用注解(如@Component
, @Service
, @Repository
等)來定義一個bean
時,Spring
會創(chuàng)建一個實現(xiàn)了AnnotatedBeanDefinition
接口的實例,如AnnotatedGenericBeanDefinition
或ScannedGenericBeanDefinition
。這個實例會保存類名、類的類型,以及類上的所有注解信息。
??GenericBeanDefinition
和AnnotatedBeanDefinition
的主要區(qū)別在于,AnnotatedBeanDefinition
保存了類上的注解信息,而GenericBeanDefinition
沒有。這就使得Spring
能夠在運行時讀取和處理這些注解,提供更豐富的功能。
??在大多數(shù)情況下,我們并不需要關(guān)心Spring
為bean
創(chuàng)建的是哪一種BeanDefinition
。Spring
會自動管理這些BeanDefinition
,并根據(jù)它們的類型以及它們所包含的信息來創(chuàng)建和配置bean
。
2.2 生成BeanDefinition的原理剖析
??這個 BeanDefinition
對象是在 Spring
啟動過程中由各種 BeanDefinitionReader
實現(xiàn)類讀取配置并生成的。
??在 Spring
中主要有三種方式來創(chuàng)建 BeanDefinition
:
- XML 配置方式:
首先,我們在 XML
文件中定義了一個 bean
:
<bean id="bookService" class="com.example.demo.service.BookService">
<property name="bookRepository" ref="bookRepository"/>
</bean>
<bean id="bookRepository" class="com.example.demo.repository.BookRepository"/>
??在這種情況下,當(dāng) Spring
啟動的時候,XmlBeanDefinitionReader
會讀取這個 XML
文件,解析其中的 <bean>
元素,并為每一個 <bean>
元素創(chuàng)建一個 BeanDefinition
對象。
簡單描述為:由XmlBeanDefinitionReader
讀取XML
文件,解析<bean>
元素并生成BeanDefinition
。
- 注解配置方式:
我們在類上使用 @Component
, @Service
, @Repository
等注解來定義 bean
,例如:
@Repository
public class BookRepository {
// ... repository methods
}
@Service
public class BookService {
private final BookRepository bookRepository;
public BookService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
// ... service methods
}
??在這種情況下,當(dāng) Spring
啟動的時候,ClassPathBeanDefinitionScanner
會掃描指定的包路徑,找到所有帶有特定注解的類,并為這些類創(chuàng)建 BeanDefinition
對象。這種方式下生成的 BeanDefinition
通常是 ScannedGenericBeanDefinition
類型。
??簡單描述為:由ClassPathBeanDefinitionScanner
掃描指定包路徑下的帶注解的類,并生成BeanDefinition
。
- Java 配置方式:
我們使用 @Configuration
和 @Bean
注解來定義配置類和 bean
,例如:
@Configuration
public class AppConfig {
@Bean
public BookRepository bookRepository() {
return new BookRepository();
}
@Bean
public BookService bookService(BookRepository bookRepository) {
return new BookService(bookRepository);
}
}
??在這種情況下,當(dāng) Spring
啟動的時候,ConfigurationClassPostProcessor
就會處理這些配置類,并交給 ConfigurationClassParser
來解析。對于配置類中每一個標(biāo)記了 @Bean
的方法,都會創(chuàng)建一個 BeanDefinition
對象。這種方式下生成的 BeanDefinition
通常是 ConfigurationClassBeanDefinition
類型。
??簡單描述為:由ConfigurationClassPostProcessor
處理標(biāo)記了@Configuration
的類,解析其中的@Bean
方法并生成BeanDefinition
。
??總的來說,不論我們選擇 XML
配置、注解配置還是 Java
配置方式,Spring
啟動時都會解析這些配置,并生成對應(yīng)的 BeanDefinition
對象,以此來指導(dǎo) Spring
容器如何創(chuàng)建和管理 Bean
實例。
??這些內(nèi)容可能比較抽象和復(fù)雜,但對于初學(xué)者來說,只需要理解:BeanDefinition
是 Spring
用來存儲 Bean
配置信息的對象,它是在 Spring
啟動過程中由 BeanDefinitionReader
讀取配置生成的,具體的生成方式取決于使用的配置方式(XML
、注解或者 Java
配置),至于其中具體的實現(xiàn)原理,以后再深入了解。
2.3 AttributeAccessor實戰(zhàn):屬性操作利器
??AttributeAccessor
是Spring
框架中的一個重要接口,它提供了一種靈活的方式來附加額外的元數(shù)據(jù)到Spring
的核心組件。在Spring
中,包括BeanDefinition
在內(nèi)的許多重要類都實現(xiàn)了AttributeAccessor
接口,這樣就可以動態(tài)地添加和獲取這些組件的額外屬性。這樣做的一個顯著好處是,開發(fā)人員可以在不改變原有類定義的情況下,靈活地管理這些組件的額外信息。
讓我們來看一個例子,全部代碼如下:
先創(chuàng)建一個Book
對象
class Book {
private String title;
private String author;
public Book() {}
public Book(String title, String author) {
this.title = title;
this.author = author;
}
// getter 和 setter 省略...
}
主程序:
package com.example.demo;
import com.example.demo.bean.Book;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class DemoApplication {
public static void main(String[] args) {
// 創(chuàng)建一個BeanDefinition, BeanDefinition是AttributeAccessor的子接口
BeanDefinition bd = new RootBeanDefinition(Book.class);
// 設(shè)置屬性
bd.setAttribute("bookAttr", "a value");
// 檢查和獲取屬性
if(bd.hasAttribute("bookAttr")) {
System.out.println("bookAttr: " + bd.getAttribute("bookAttr"));
// 移除屬性
bd.removeAttribute("bookAttr");
System.out.println("bookAttr: " + bd.getAttribute("bookAttr"));
}
}
}
??在這個例子中,我們創(chuàng)建了一個RootBeanDefinition
實例來描述如何創(chuàng)建一個Book
類的實例。RootBeanDefinition
是BeanDefinition
的實現(xiàn),而BeanDefinition
實現(xiàn)了AttributeAccessor
接口,因此RootBeanDefinition
也就繼承了AttributeAccessor
的方法。
有人可能會疑問,Book并沒有bookAttr這個成員變量,這是怎么賦值的?
??在Spring
框架中,AttributeAccessor
接口定義的方法是為了附加、獲取和移除與某個對象(例如RootBeanDefinition
)相關(guān)聯(lián)的元數(shù)據(jù),而不是操作對象(例如Book
)本身的字段。
??所以,在RootBeanDefinition
實例上調(diào)用setAttribute("bookAttr", "a value")
方法時,其實并不是在Book
實例上設(shè)置一個名為bookAttr
的字段。而是在RootBeanDefinition
實例上附加了一個元數(shù)據(jù),元數(shù)據(jù)的鍵是"bookAttr"
,值是"a value"
。
??后續(xù)使用getAttribute("bookAttr")
方法時,它將返回之前設(shè)置的元數(shù)據(jù)值"a value"
,而不是嘗試訪問Book
類的bookAttr
字段(實際上Book
類并沒有bookAttr
字段)。
??簡單來說,這些元數(shù)據(jù)是附加在RootBeanDefinition
對象上的,而不是附加在由RootBeanDefinition
對象描述的Book
實例上的。
運行結(jié)果:
總結(jié):
??BeanDefinition
是實現(xiàn)了AttributeAccessor
接口的一個重要的類,BeanDefinition
對象是 Spring
框架用來存儲 bean
配置信息的數(shù)據(jù)結(jié)構(gòu)。當(dāng)我們在配置類中使用 @Bean
、@Scope
、@Lazy
等注解定義一個 bean
時,Spring
會為這個 bean
創(chuàng)建一個 BeanDefinition
對象,并將這些注解的元數(shù)據(jù)附加到這個 BeanDefinition
對象上。
??當(dāng) Spring
容器在后續(xù)需要創(chuàng)建 bean
實例時,它會查看這個 BeanDefinition
對象,按照其中的元數(shù)據(jù)(如 scope
、lazy
初始化、初始化和銷毀方法等)來創(chuàng)建和管理 bean
實例。這些元數(shù)據(jù)并不會直接附加到 bean
實例上,而是存儲在 BeanDefinition
對象中,由 Spring
容器來管理和使用。
??所以,當(dāng)我們在 main
方法中從 ApplicationContext
獲取 BeanDefinition
并打印其屬性時,我們實際上是在查看 Spring
框架用來管理 bean
的內(nèi)部數(shù)據(jù)結(jié)構(gòu),而不是直接查看 bean
實例本身的狀態(tài)。
??這種方法的好處是,它將這些額外的元數(shù)據(jù)與bean
實例本身分離,這樣就可以在不修改bean
類的情況下靈活地改變這些元數(shù)據(jù),而且AttributeAccessor
可以在同一個JVM
進(jìn)程中的不同線程間共享數(shù)據(jù)。這也是為什么我們可以通過修改配置文件或注解來改變bean
的范圍、是否是懶加載等,而不需要修改bean
的類定義。
3. BeanDefinition回顧及總結(jié)
??在我們深入探討Spring
框架的過程中,我們已經(jīng)了解了BeanDefinition
是Spring
中非常關(guān)鍵的一個概念。BeanDefinition
的主要職責(zé)是作為一個數(shù)據(jù)對象,存儲了關(guān)于如何創(chuàng)建、初始化、配置一個具體的Bean
實例的詳細(xì)信息。
特別是,BeanDefinition
中包含以下主要信息:文章來源:http://www.zghlxwxcb.cn/news/detail-612536.html
-
完全限定的類名,以便
Spring
容器通過反射創(chuàng)建Bean
實例。 -
Bean的名稱和別名,用于在應(yīng)用中引用和查找
Bean
。 -
Bean的作用域,如單例或原型,決定了
Spring
如何管理Bean
實例的生命周期。 -
構(gòu)造函數(shù)參數(shù)和屬性值,用于實例化
Bean
和依賴注入。 -
自動裝配模式,指示
Spring
如何自動注入依賴。 -
初始化和銷毀方法,讓
Spring
知道在Bean
生命周期的特定時刻如何執(zhí)行自定義邏輯。 -
Bean的依賴關(guān)系,告訴
Spring
在創(chuàng)建當(dāng)前Bean
之前需要先創(chuàng)建哪些Bean
。
??無論我們使用哪種配置方式(XML
、注解或Java
配置),Spring
在啟動時都會解析這些配置,然后生成相應(yīng)的BeanDefinition
對象。這些BeanDefinition
對象就像是Spring
容器內(nèi)部的配方,告訴Spring
容器如何創(chuàng)建和配置各個Bean
。文章來源地址http://www.zghlxwxcb.cn/news/detail-612536.html
歡迎一鍵三連~
有問題請留言,大家一起探討學(xué)習(xí)
----------------------Talk is cheap, show me the code-----------------------
到了這里,關(guān)于Spring高手之路11——BeanDefinition解密:構(gòu)建和管理Spring Beans的基石的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!