最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入分析Spring BeanDefinition的構(gòu)造元信息

 更新時間:2024年01月14日 09:02:37   作者:FirstMrRight  
Bean Definition是一個包含Bean元數(shù)據(jù)的對象,它描述了如何創(chuàng)建Bean實(shí)例、Bean屬性的值以及Bean之間的依賴關(guān)系,本文將帶大家深入分析Spring BeanDefinition的構(gòu)造元信息,需要的朋友可以參考下

Spring BeanDefinition元信息定義方式

Bean Definition是一個包含Bean元數(shù)據(jù)的對象。它描述了如何創(chuàng)建Bean實(shí)例、Bean屬性的值以及Bean之間的依賴關(guān)系??梢允褂枚喾N方式來定義 Bean Definition 元信息,包括:

  • XML 配置文件:使用<bean>標(biāo)簽定義 Bean 元數(shù)據(jù),可以指定 Bean 類型、屬性值和依賴項(xiàng)等信息。
  • 注解:使用@Component、@Service、@Repository 等注解標(biāo)記 Bean 類,并使用 @Autowired注解注入依賴項(xiàng)。
  • Java 配置類:使用@Configuration@Bean注解定義Bean元數(shù)據(jù),可以指定 Bean 類型、屬性值和依賴項(xiàng)等信息。

除此之外,還可以通過實(shí)現(xiàn) BeanDefinitionRegistryPostProcessor 接口來自定義 Bean Definition 的生成過程。這個接口有一個方法 postProcessBeanDefinitionRegistry(),允許開發(fā)人員動態(tài)地添加、修改或刪除Bean Definition元信息。

XML配置文件定義Bean的元數(shù)據(jù)

<bean id="user" class="org.thinging.in.spring.ioc.overview.domain.User">
  <property name="id" value="1"/>
  <property name="name" value="Liutx"/>
</bean>

注解定義Bean的元數(shù)據(jù)

@Service(value = "HelloService")
public class HelloService {

    private final Logger logger = LoggerFactory.getLogger(HelloService.class);

    private final HelloAsyncService helloAsyncService;

        public HelloService(HelloAsyncService helloAsyncService) {
        this.helloAsyncService = helloAsyncService;
    }
}

value = "HelloService" 即為Bean:HelloService的元數(shù)據(jù),在構(gòu)造方法中的依賴關(guān)系同樣屬于元數(shù)據(jù)。

Java 配置類定義Bean的元數(shù)據(jù)

@Component(value = "balanceRedisProcessor")
public class BalanceRedisProcessorService implements EntryHandler<Balance>, Runnable {

    @Autowired(required = true)
    public BalanceRedisProcessorService(RedisUtils redisUtils,
                                        CanalConfig canalConfig,
                                        @Qualifier("ownThreadPoolExecutor") Executor executor, RocketMQProducer rocketMqProducer) {
        this.redisUtils = redisUtils;
        this.canalConfig = canalConfig;
        this.executor = executor;
        this.rocketMQProducer = rocketMqProducer;
    }
}

@Component(value = "balanceRedisProcessor") 是Bean:BalanceRedisProcessorService的元數(shù)據(jù),在構(gòu)造方法中的依賴關(guān)系同樣屬于元數(shù)據(jù)。

BeanDefinition的元數(shù)據(jù)解析

在Spring中,無論是通過XML、注解、Java配置類定義Bean元數(shù)據(jù),最終都是需要轉(zhuǎn)換成BeanDefinition對象,然后被注冊到Spring容器中。

BeanDefinition的創(chuàng)建過程,確實(shí)是通過AbstractBeanDefinition及其派生類、``等一系列工具類實(shí)現(xiàn)的。

  • 當(dāng)我們使用XML配置時,Spring會解析XML文件,將其中的Bean元數(shù)據(jù)信息轉(zhuǎn)換成對應(yīng)的BeanDefinition對象,然后注冊到Spring容器中。在這個過程中,Spring內(nèi)部會使用XmlBeanDefinitionReader等相關(guān)工具類,將XML文件中定義的Bean元數(shù)據(jù)轉(zhuǎn)換成BeanDefinition對象。
  • 當(dāng)我們使用注解方式或Java配置類方式定義Bean元數(shù)據(jù)時,Spring會掃描相應(yīng)的注解或Java配置類,然后根據(jù)其定義生成對應(yīng)的BeanDefinition對象,并注冊到Spring容器中。在這個過程中,Spring內(nèi)部會使用AnnotationConfigApplicationContext等相關(guān)工具類,將注解或Java配置類中定義的Bean元數(shù)據(jù)轉(zhuǎn)換成BeanDefinition對象。

源碼分析XML是如何轉(zhuǎn)化為Spring BeanDefinition的

將xml文件中的配置轉(zhuǎn)為為BeanDefinition需要依賴自XmlBeanDefinitionReader類中的loadBeanDefinitions方法。

選自:Spring Framework 5.2.20 RELEASE版本的XmlBeanDefinitionReader。

private final ThreadLocal<Set<EncodedResource>> resourcesCurrentlyBeingLoaded =
        new NamedThreadLocal<Set<EncodedResource>>("XML bean definition resources currently being loaded"){
            @Override
            protected Set<EncodedResource> initialValue() {
                return new HashSet<>(4);
            }
        };

/**
 * Load bean definitions from the specified XML file.
 * @param encodedResource the resource descriptor for the XML file,
 * allowing to specify an encoding to use for parsing the file
 * @return the number of bean definitions found
 * @throws BeanDefinitionStoreException in case of loading or parsing errors
 */
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    Assert.notNull(encodedResource, "EncodedResource must not be null");
    if (logger.isTraceEnabled()) {
        logger.trace("Loading XML bean definitions from " + encodedResource);
    }

    Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();

    if (!currentResources.add(encodedResource)) {
        throw new BeanDefinitionStoreException(
                "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
    }

    try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
        InputSource inputSource = new InputSource(inputStream);
        if (encodedResource.getEncoding() != null) {
            inputSource.setEncoding(encodedResource.getEncoding());
        }
        // 實(shí)際上從指定的 XML 文件加載 Bean 定義
        return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
    }
    catch (IOException ex) {
        throw new BeanDefinitionStoreException(
                "IOException parsing XML document from " + encodedResource.getResource(), ex);
    }
    finally {
        currentResources.remove(encodedResource);
        if (currentResources.isEmpty()) {
            this.resourcesCurrentlyBeingLoaded.remove();
        }
    }
}


//實(shí)際上從指定的 XML 文件加載 Bean 定義
/**
 * Actually load bean definitions from the specified XML file.
 * @param inputSource the SAX InputSource to read from
 * @param resource the resource descriptor for the XML file
 * @return the number of bean definitions found
 * @throws BeanDefinitionStoreException in case of loading or parsing errors
 * @see #doLoadDocument
 * @see #registerBeanDefinitions
 */
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
        throws BeanDefinitionStoreException {

    try {
        Document doc = doLoadDocument(inputSource, resource);
        int count = registerBeanDefinitions(doc, resource);
        if (logger.isDebugEnabled()) {
            logger.debug("Loaded " + count + " bean definitions from " + resource);
        }
        return count;
    }
}
  • 使用ThreadLocal線程級別的變量存儲帶有編碼資源的集合,保證每個線程都可以訪問到XmlBeanDefinitionReader在加載XML配置文件時當(dāng)前正在加載的資源,以確保加載過程中的完整性和正確性。
  • ThreadLocal中獲取到當(dāng)前正在加載的xml資源,轉(zhuǎn)換為輸入流
  • 開始執(zhí)行doLoadBeanDefinitions,實(shí)際上從指定的 XML 文件加載 Bean 定義,該方法會返回加載的Bean定義數(shù)量。
  • doLoadBeanDefinitions方法中,首先調(diào)用doLoadDocument方法加載XML文件并生成一個Document對象。
  • 然后,調(diào)用registerBeanDefinitions方法來注冊Bean定義,將其放入Spring容器中。該方法會返回注冊的Bean定義數(shù)量。
  • 最后,根據(jù)需要記錄日志信息,并返回加載的Bean定義數(shù)量。

源碼分析配置類、注解是如何轉(zhuǎn)化為Spring BeanDefinition的

在Spring中,配置類和注解都可以被轉(zhuǎn)換為Bean定義(BeanDefinition)。下面是關(guān)于如何將配置類和注解轉(zhuǎn)換為Bean定義的簡要源碼分析:

  • 配置類轉(zhuǎn)換為Bean定義:
    • 當(dāng)使用Java配置類時,Spring會通過解析配置類中的注解來生成相應(yīng)的Bean定義。主要實(shí)現(xiàn)是通過ConfigurationClassParser類完成的。
    • ConfigurationClassParser會解析配置類上的注解,包括@Configuration@ComponentScan、@Bean等,然后將其轉(zhuǎn)換為對應(yīng)的Bean定義。
    • 在解析過程中,Spring會創(chuàng)建一個ConfigurationClass對象表示配置類,并根據(jù)不同的注解類型生成相應(yīng)的Bean定義,包括RootBeanDefinitionMethodMetadata。
    • RootBeanDefinition代表配置類本身,而MethodMetadata代表配置類中的方法上的注解,例如@Bean注解。
    • 最終,這些生成的Bean定義會被注冊到DefaultListableBeanFactory中,以供后續(xù)的Bean實(shí)例化和依賴注入。
  • 注解轉(zhuǎn)換為Bean定義:
    • 當(dāng)使用注解方式配置Bean時,Spring會掃描指定的包或類,并解析其中的注解來生成Bean定義。
    • Spring提供了AnnotationBeanDefinitionReader類用于處理注解,它會掃描指定的包路徑或類,并根據(jù)注解生成相應(yīng)的Bean定義。
    • 在掃描過程中,AnnotationBeanDefinitionReader會解析常見的注解,比如@Component、@Controller、@Service、@Repository等,然后生成相應(yīng)的Bean定義。
    • 注解生成的Bean定義同樣會被注冊到DefaultListableBeanFactory中,以供后續(xù)的Bean實(shí)例化和依賴注入。

總而言之,無論是配置類還是注解,Spring都會通過解析注解并生成對應(yīng)的Bean定義,最終將這些Bean定義注冊到DefaultListableBeanFactory中。這樣,在容器啟動時,Spring就能夠根據(jù)這些Bean定義來實(shí)例化Bean并進(jìn)行依賴注入。

配置類、注解轉(zhuǎn)換為Spring BeanDefition源碼后續(xù)博客中展示,敬請期待。

如何手動構(gòu)造BeanDefinition

Bean定義

public class User {

    private Long id;

    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + ''' +
                '}';
    }
}

通過BeanDefinitionBuilder構(gòu)建

//通過BeanDefinitionBuilder構(gòu)建
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
//通過屬性設(shè)置
beanDefinitionBuilder.addPropertyValue("id", 1L)
        .addPropertyValue("name","公眾號:種棵代碼技術(shù)樹");

//獲取BeanDefinition實(shí)例
BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
// BeanDefinition 并非 Bean 終態(tài),可以自定義修改
System.out.println(beanDefinition);

通過AbstractBeanDefinition以及派生類

// 2. 通過 AbstractBeanDefinition 以及派生類
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
//設(shè)置Bean類型
genericBeanDefinition.setBeanClass(User.class);
//通過 MutablePropertyValues 批量操作屬性
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("id",1L)
        .add("name","公眾號:種棵代碼技術(shù)樹");
// 通過 set MutablePropertyValues 批量操作屬性
genericBeanDefinition.setPropertyValues(propertyValues);

最后

以上就是深入分析Spring BeanDefinition的構(gòu)造元信息的詳細(xì)內(nèi)容,更多關(guān)于Spring BeanDefinition構(gòu)造元信息的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java中讀取YAML文件配置信息常見問題及解決方法

    Java中讀取YAML文件配置信息常見問題及解決方法

    這篇文章主要介紹了Java中讀取YAML文件配置信息常見問題及解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-07-07
  • SpringBoot整合Security實(shí)現(xiàn)權(quán)限控制框架(案例詳解)

    SpringBoot整合Security實(shí)現(xiàn)權(quán)限控制框架(案例詳解)

    Spring Security是一個能夠?yàn)榛赟pring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問控制解決方案的安全框,是一個重量級的安全管理框架,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-08-08
  • SpringBoot2線程池定義使用方法解析

    SpringBoot2線程池定義使用方法解析

    這篇文章主要介紹了SpringBoot2線程池定義使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • SpringBoot使用iText7實(shí)現(xiàn)將HTML轉(zhuǎn)成PDF并添加頁眉頁腳水印

    SpringBoot使用iText7實(shí)現(xiàn)將HTML轉(zhuǎn)成PDF并添加頁眉頁腳水印

    這篇文章主要為大家詳細(xì)介紹了SpringBoot使用iText7實(shí)現(xiàn)將HTML轉(zhuǎn)成PDF并添加頁眉頁腳水印的相關(guān)知識,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • mybatis-plus使用xml自定義sql語句方式

    mybatis-plus使用xml自定義sql語句方式

    這篇文章主要介紹了mybatis-plus使用xml自定義sql語句方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 關(guān)于SpringBoot微服務(wù)發(fā)布與部署的三種方式

    關(guān)于SpringBoot微服務(wù)發(fā)布與部署的三種方式

    SpringBoot 框架只提供了一套基于可執(zhí)行 jar 包(executable jar)格式的標(biāo)準(zhǔn)發(fā)布形式,但并沒有對部署做過多的界定,而且為了簡化可執(zhí)行 jar 包的生成,SpringBoot 提供了相應(yīng)的 Maven 項(xiàng)目插件,需要的朋友可以參考下
    2023-05-05
  • 詳解Spring中@Valid和@Validated注解用法

    詳解Spring中@Valid和@Validated注解用法

    本文將以新增一個員工為功能切入點(diǎn),以常規(guī)寫法為背景,慢慢烘托出?@Valid?和?@Validated?注解用法詳解,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-07-07
  • Java中一個線程執(zhí)行死循環(huán)有什么后果

    Java中一個線程執(zhí)行死循環(huán)有什么后果

    這篇文章主要為大家詳細(xì)介紹了Java中一個線程執(zhí)行死循環(huán)有什么后果,當(dāng)一個線程在執(zhí)行死循環(huán)時會影響另外一個線程嗎,下面為大家揭曉
    2016-05-05
  • Java 中 System.load 和 System.loadLibrary 方法使用舉例

    Java 中 System.load 和 System.loadLibrary&

    在Java開發(fā)中,有時候我們需要調(diào)用本地代碼(如 C、C++ 編寫的代碼)來實(shí)現(xiàn)一些特定的功能,比如提高性能、訪問底層硬件等,本文給大家介紹Java中System.load和System.loadLibrary方法使用舉例,感興趣的朋友一起看看吧
    2025-08-08
  • 智能手表開發(fā)API接口

    智能手表開發(fā)API接口

    這篇文章主要介紹了智能手表開發(fā)API接口,使用圖靈機(jī)器人平臺接口實(shí)現(xiàn)天氣預(yù)報,非常簡單實(shí)用,這里推薦給大家。
    2015-03-03

最新評論

塔河县| 建始县| 时尚| 德安县| 青海省| 灯塔市| 永嘉县| 五莲县| 衡南县| 梨树县| 东海县| 波密县| 邵东县| 苗栗县| 衡南县| 荔浦县| 南皮县| 措美县| 金坛市| 四川省| 乐亭县| 厦门市| 万山特区| 梅河口市| 靖远县| 明溪县| 三明市| 江源县| 滦平县| 宿州市| 惠州市| 西畴县| 若羌县| 辛集市| 云梦县| 万源市| 芒康县| 油尖旺区| 临西县| 台安县| 绥棱县|