国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Spring高手之路11——BeanDefinition解密:構(gòu)建和管理Spring Beans的基石

這篇具有很好參考價值的文章主要介紹了Spring高手之路11——BeanDefinition解密:構(gòu)建和管理Spring Beans的基石。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

??BeanDefinitionSpring中一個非常重要的概念,它包含了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ù)。我們可以通過BeanDefinitiongetBeanClassName()方法獲取到這個全限定類名。

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的使用。

??從上面可以看到,BeanDefinitionSpring 框架中用來描述 Bean 的元數(shù)據(jù)對象,這個元數(shù)據(jù)包含了關(guān)于 Bean 的一些基本信息,包括以下幾個方面:

  • Bean 的類信息: 這是 Bean 的全限定類名,即這個 Bean 實例化后的具體類型。

  • Bean 的屬性信息: 包括了如 Bean 的作用域(是單例還是原型)、是否為主要的 Beanprimary)、描述信息等。

  • 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,Spring高手之路,BeanDefinition,Spring框架,IoC容器,元信息,Bean配置,原力計劃

??這個例子包含了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 的作用域,例如 singletonprototype。如果 scopesingleton,那么 Spring 容器將只創(chuàng)建一個 Bean 實例并在每次請求時返回這個實例。如果 scopeprototype,那么每次請求 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,那么我們可以在 BookServiceBeanDefinition 中設(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的角色。BeanDefinitionSpring中的核心組件,它定義了bean的配置信息,包括類名、作用域、構(gòu)造器參數(shù)、屬性值等。下面我們來看看BeanDefinitionSpring中的設(shè)計是如何的。

通過IDEA我們可以得到如下的繼承關(guān)系圖:

beandefinition,Spring高手之路,BeanDefinition,Spring框架,IoC容器,元信息,Bean配置,原力計劃

雖然有許多接口、抽象類和擴(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接口的實例,如AnnotatedGenericBeanDefinitionScannedGenericBeanDefinition。這個實例會保存類名、類的類型,以及類上的所有注解信息。

??GenericBeanDefinitionAnnotatedBeanDefinition的主要區(qū)別在于,AnnotatedBeanDefinition保存了類上的注解信息,而GenericBeanDefinition沒有。這就使得Spring能夠在運行時讀取和處理這些注解,提供更豐富的功能。

??在大多數(shù)情況下,我們并不需要關(guān)心Springbean創(chuàng)建的是哪一種BeanDefinitionSpring會自動管理這些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é)者來說,只需要理解:BeanDefinitionSpring 用來存儲 Bean 配置信息的對象,它是在 Spring 啟動過程中由 BeanDefinitionReader 讀取配置生成的,具體的生成方式取決于使用的配置方式(XML、注解或者 Java 配置),至于其中具體的實現(xiàn)原理,以后再深入了解。

2.3 AttributeAccessor實戰(zhàn):屬性操作利器

??AttributeAccessorSpring框架中的一個重要接口,它提供了一種靈活的方式來附加額外的元數(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類的實例。RootBeanDefinitionBeanDefinition的實現(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é)果:

beandefinition,Spring高手之路,BeanDefinition,Spring框架,IoC容器,元信息,Bean配置,原力計劃

總結(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ù)(如 scopelazy 初始化、初始化和銷毀方法等)來創(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)了解了BeanDefinitionSpring中非常關(guān)鍵的一個概念。BeanDefinition的主要職責(zé)是作為一個數(shù)據(jù)對象,存儲了關(guān)于如何創(chuàng)建、初始化、配置一個具體的Bean實例的詳細(xì)信息。

特別是,BeanDefinition中包含以下主要信息:

  • 完全限定的類名,以便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)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Spring高手之路-SpringBean的生命周期

    Spring高手之路-SpringBean的生命周期

    目錄 SpringBean的生命周期 整體介紹 詳細(xì)介紹 1.實例化Bean 2.設(shè)置屬性值 3.檢查Aware 4.調(diào)用BeanPostProcessor的前置處理方法 5.調(diào)用InitializingBean的afterPropertiesSet方法 6.調(diào)用自定義init-method方法 7.調(diào)用BeanPostProcessor的后置處理方法 8.注冊Destruction回調(diào) 9.Bean準(zhǔn)備就緒 10.調(diào)用DisposableBean的d

    2024年02月03日
    瀏覽(23)
  • Spring高手之路-Spring在業(yè)務(wù)中常見的使用方式

    目錄 通過IOC實現(xiàn)策略模式 通過AOP實現(xiàn)攔截增強(qiáng) 1.參數(shù)檢驗 2.緩存邏輯 3.日志記錄 通過Event異步解耦 通過Spring管理事務(wù) 1.聲明式事務(wù) 2.編程式事務(wù) 3.需要注意的問題 不能在事務(wù)中處理分布式緩存 不能在事務(wù)中執(zhí)行 RPC 操作 不過度使用聲明式事務(wù) 很多時候,我們需要對不同的

    2024年01月19日
    瀏覽(22)
  • Spring高手之路9——掌握Spring條件裝配的秘密武器

    Spring高手之路9——掌握Spring條件裝配的秘密武器

    ??在 Spring 框架中,條件裝配( Conditional Configuration )是一個非常重要的特性,它允許開發(fā)者根據(jù)滿足的條件,動態(tài)地進(jìn)行 Bean 的注冊或是創(chuàng)建。這樣就可以根據(jù)不同的環(huán)境或配置,創(chuàng)建不同的 Bean 實例,這一特性對于創(chuàng)建可配置和模塊化的應(yīng)用是非常有用的。 Spring 提供了一

    2024年02月16日
    瀏覽(23)
  • Spring高手之路10——解鎖Spring組件掃描的新視角

    Spring高手之路10——解鎖Spring組件掃描的新視角

    ??首先,我們將探討一些 Spring 框架中 IOC ( Inversion of Control )的高級特性,特別是組件掃描的相關(guān)知識。組件掃描是 Spring 框架中一個重要的特性,它可以自動檢測并實例化帶有特定注解(如 @Component , @Service , @Controller 等)的類,并將它們注冊為 Spring 上下文中的 bean 。這

    2024年02月16日
    瀏覽(26)
  • Spring高手之路-@Autowired和@Resource注解異同點

    Spring高手之路-@Autowired和@Resource注解異同點

    目錄 概述 相同點 1.都可以實現(xiàn)依賴注入 2.都可以用于注入任意類型的Bean 3.都支持通過名稱、類型匹配進(jìn)行注入 不同點 1.來源不同。 2.包含的屬性不同 3.匹配方式(裝配順序)不同。 4.支持的注入對象類型不同 5.應(yīng)用地方不同 @Autowired 和 @Resource 是在 Java 開發(fā)中用于實現(xiàn)依賴

    2024年02月03日
    瀏覽(26)
  • Spring高手之路5——徹底掌握Bean的生命周期

    Spring高手之路5——徹底掌握Bean的生命周期

    在 Spring IOC 容器中, Bean 的生命周期大致如下: 實例化:當(dāng)啟動 Spring 應(yīng)用時, IOC 容器就會為在配置文件中聲明的每個 bean 創(chuàng)建一個實例。 屬性賦值:實例化后, Spring 就通過反射機(jī)制給 Bean 的屬性賦值。 調(diào)用初始化方法:如果 Bean 配置了初始化方法, Spring 就會調(diào)用它。

    2024年02月09日
    瀏覽(20)
  • Spring高手之路8——Spring Bean模塊裝配的藝術(shù):@Import詳解

    Spring高手之路8——Spring Bean模塊裝配的藝術(shù):@Import詳解

    ??在 Spring 中,手動裝配通常是指通過 XML 配置文件明確指定 Bean 及其依賴,或者在代碼中直接使用 new 創(chuàng)建對象并設(shè)定依賴關(guān)系。 ??然而,隨著 Spring 2.0 引入注解,以及 Spring 3.0 全面支持注解驅(qū)動開發(fā),這個過程變得更加自動化。例如,通過使用 @Component + @Compo

    2024年02月13日
    瀏覽(26)
  • Spring高手之路3——揭秘Spring依賴注入和SpEL表達(dá)式

    Spring高手之路3——揭秘Spring依賴注入和SpEL表達(dá)式

    本篇會給大家舉出各種 Spring 屬性依賴注入的例子,方便大家理解。 我們在前面的文章中已經(jīng)使用過 XML 進(jìn)行 setter 方法的屬性注入了,下面讓我們再來回顧一下: 我們在前面的文章中也學(xué)習(xí)過如何在 bean 創(chuàng)建時通過編程方式設(shè)置屬性: 使用XML進(jìn)行setter方法注入 首先,我們需

    2024年02月08日
    瀏覽(32)
  • Spring高手之路13——BeanFactoryPostProcessor與BeanDefinitionRegistryPostProcessor解析

    Spring高手之路13——BeanFactoryPostProcessor與BeanDefinitionRegistryPostProcessor解析

    ?? BeanFactoryPostProcessor 位于 org.springframework.beans.factory.config 包中。它與 BeanPostProcessor 有相似的核心邏輯,但它們之間的主要區(qū)別在于它們所操作的對象。 BeanFactoryPostProcessor 的主要目的是對 Bean 的配置元數(shù)據(jù)進(jìn)行操作,這意味著它可以影響 Bean 的初始配置數(shù)據(jù)。 ??在 Sp

    2024年02月11日
    瀏覽(58)
  • Spring高手之路15——掌握Spring事件監(jiān)聽器的內(nèi)部邏輯與實現(xiàn)

    Spring高手之路15——掌握Spring事件監(jiān)聽器的內(nèi)部邏輯與實現(xiàn)

    在閱讀本文之前需要你已經(jīng)對事件監(jiān)聽器有了簡單的了解,或去閱讀前面的文章《 Spring高手之路7——事件機(jī)制與監(jiān)聽器的全面探索 》 ??在 Spring 中, ApplicationContext 可以形成一個層次結(jié)構(gòu),通常由主容器和多個子容器組成。一個常見的疑問是:當(dāng)一個事件在其中一個容器

    2024年02月06日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包