摘要:但是這些對象在容器中,到底是以什么形式存在,具有哪些屬性行為呢今天我們進入到源碼來一探究竟。只對注解有效,配置文件中可以通過顯示注入配置為主要候選。至于各屬性的詳細使用和注意事項,后續會有多帶帶的文章來解析,盡情期待
Spring版本為5.1.5簡述
用過spring的人都知道,我們將對象注入到spring容器中,交給spring來幫我們管理。這種對象我們稱之為bean對象。但是這些bean對象在spring容器中,到底是以什么形式存在,具有哪些屬性、行為呢?今天我們進入到spring源碼來一探究竟。
bean的創建工廠BeanFactory有個默認實現類DefaultListableBeanFactory,內部有個存放所有注入bean對象信息的Map
/** Map of bean definition objects, keyed by bean name. */ private final MapbeanDefinitionMap = new ConcurrentHashMap<>(256);
Map的value對象BeanDefinition就是spring中對bean的定義和描述,具體概述如下:
屬性 | 行為 | 解釋 |
---|---|---|
parentName | String getParentName(); void setParentName(@Nullable String parentName); |
bean定義對象的父類定義對象名稱 |
beanClassName | String getBeanClassName(); void setBeanClassName(@Nullable String beanClassName); |
bean對象的實際class類 |
scope | String getScope(); void setScope(@Nullable String scope); |
bean對象是否為單例 |
lazyInit | boolean isLazyInit(); void setLazyInit(boolean lazyInit); |
是否懶加載 |
dependsOn | String[] getDependsOn(); void setDependsOn(@Nullable String... dependsOn); |
設置依賴的bean對象,被依賴的bean對象總是會比當前bean對象先創建 |
autowireCandidate | boolean isAutowireCandidate(); void setAutowireCandidate(boolean autowireCandidate); |
設置是否可以自動注入。只對@Autowired注解有效,配置文件中可以通過property顯示注入 |
primary | boolean isPrimary(); void setPrimary(boolean primary); |
配置bean為主要候選bean。當同一個接口的多個實現類或者一個類多次注入到spring容器時,通過該屬性來配置某個bean為主候選bean,通過類型來注入時,默認為使用主候選bean注入 |
factoryBeanName | String getFactoryBeanName(); void setFactoryBeanName(@Nullable String factoryBeanName); |
設置創建bean的工廠名稱 |
factoryMethodName | String getFactoryMethodName(); void setFactoryMethodName(@Nullable String factoryMethodName); |
設置創建bean的工廠中,創建bean的具體方法 |
initMethodName | String getInitMethodName(); void setInitMethodName(@Nullable String initMethodName); |
設置創建bean時,默認初始化的方法 |
destroyMethodName | String getDestroyMethodName(); void setDestroyMethodName(@Nullable String destroyMethodName); |
設置銷毀bean時調用的方法名稱。注意需要調用context的close()方法才會調用 |
role | int getRole(); void setRole(int role); |
設置bean的分類。 APPLICATION:用戶 INFRASTRUCTURE:完全內部使用,與用戶無關 SUPPORT:某些復雜配置的一部分 |
description | String getDescription(); void setDescription(@Nullable String description); |
對bean對象的描述 |
ConstructorArgumentValues | getConstructorArgumentValues(); | 記錄構造函數注入屬性,通過bean的水性constructor-arg來注入 |
MutablePropertyValues | getPropertyValues(); | 普通屬性集合 |
注意:BeanDefinition是一個接口,內部只定義了bean對象的一些基本行為。上表中的屬性在BeanDefinition中并不是真實存在的,只是通過set、get方法來設置和獲取。以下抽取出部分BeanDefinition源代碼供大家感知下
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { /** * Override the target scope of this bean, specifying a new scope name. * @see #SCOPE_SINGLETON * @see #SCOPE_PROTOTYPE */ void setScope(@Nullable String scope); /** * Return the name of the current target scope for this bean, * or {@code null} if not known yet. */ @Nullable String getScope(); }實際使用
假設有以下兩個bean,Java代碼如下
MyTestBean
package com.yuanweiquan.learn.bean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Description; public class MyTestBean { @Autowired private AutowireCandidateBean autowireCandidateBean; public void init() { System.out.println("inti MyTestBean"); } public AutowireCandidateBean getAutowireCandidateBean() { return autowireCandidateBean; } public void setAutowireCandidateBean(AutowireCandidateBean bean) { this.autowireCandidateBean = bean; } }
AutowireCandidateBean
package com.yuanweiquan.learn.bean; public class AutowireCandidateBean { public void initBean() { System.out.println("init AutowireCandidateBean"); } public void destroyBean() { System.out.println("destroy AutowireCandidateBean"); } }
下面看如何在配置文件applicationContext.xml來進行配置
autowireCandidateBean description
接下來就是測試代碼
FileSystemXmlApplicationContext factory = new FileSystemXmlApplicationContext("classpath:applicationContext.xml"); BeanDefinition myTestBeanDefinition = factory.getBeanFactory().getBeanDefinition("autowireCandidateBean"); //輸出 System.out.println("bean description:" + myTestBeanDefinition.getDescription()); System.out.println("bean class name:" + myTestBeanDefinition.getBeanClassName()); System.out.println("parent name:" + myTestBeanDefinition.getParentName()); System.out.println("scope:" + myTestBeanDefinition.getScope()); System.out.println("is lazyinit:" + myTestBeanDefinition.isLazyInit()); System.out.println("depends On:" + myTestBeanDefinition.getDependsOn()); System.out.println("is autowireCandidate:" + myTestBeanDefinition.isAutowireCandidate()); System.out.println("is primary:" + myTestBeanDefinition.isPrimary()); System.out.println("factory bean name:"+myTestBeanDefinition.getFactoryBeanName()); System.out.println("factory bean method name:" + myTestBeanDefinition.getFactoryMethodName()); System.out.println("init method name:" + myTestBeanDefinition.getInitMethodName()); System.out.println("destory method name:" + myTestBeanDefinition.getDestroyMethodName()); System.out.println("role:" + myTestBeanDefinition.getRole()); //關閉context,否則不會調用bean的銷毀方法 factory.close();
控制臺輸出如下
init AutowireCandidateBean inti MyTestBean bean description:autowireCandidateBean description bean class name:com.yuanweiquan.learn.bean.AutowireCandidateBean parent name:myTestBean scope:singleton is lazyinit:false depends On:null is autowireCandidate:true is primary:true factory bean name:null factory bean method name:null init method name:initBean destory method name:destroyBean role:0 destroy AutowireCandidateBean
到此為止,通過上面的信息,我們能清晰的看到各屬性對應的值。上述測試代碼的目的是讓我們大家能看到bean在spring容器中,以什么樣子的形式存在,具體有哪些屬性,屬性的值以及默認值是多少。也算初步的揭開了spring容器中bean的面紗,其實并沒有我們想象中的那么神秘。至于各屬性的詳細使用和注意事項,后續會有多帶帶的文章來解析,盡情期待!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73856.html
摘要:前言以下源碼基于版本解析。實現源碼分析對于的實現,總結來說就是定位加載和注冊。定位就是需要定位配置文件的位置,加載就是將配置文件加載進內存注冊就是通過解析配置文件注冊。下面我們從其中的一種使用的方式一步一步的分析的實現源碼。 前言 以下源碼基于Spring 5.0.2版本解析。 什么是IOC容器? 容器,顧名思義可以用來容納一切事物。我們平常所說的Spring IOC容器就是一個可以容...
摘要:在介紹自定義標簽解析前,先放一張圖幫助大家理解以下是如何從文件中解析并加載的。自定義標簽比如的值為根據獲取到的,獲取對應的對象。關于和加載先后順序的問題最后再集合一個小例子總結下吧當我們先解析了元素時,我們會遍歷所有已經注冊注冊表中。 今天我們來談談 Dubbo XML 配置相關內容。關于這部分內容我打算分為以下幾個部分進行介紹: Dubbo XML Spring 自定義 XML 標...
摘要:簡介為了寫容器源碼分析系列的文章,我特地寫了一篇容器的導讀文章。在做完必要的準備工作后,從本文開始,正式開始進入源碼分析的階段。從緩存中獲取單例。返回以上就是和兩個方法的分析。 1. 簡介 為了寫 Spring IOC 容器源碼分析系列的文章,我特地寫了一篇 Spring IOC 容器的導讀文章。在導讀一文中,我介紹了 Spring 的一些特性以及閱讀 Spring 源碼的一些建議。在...
摘要:本文是針對的來進行解析并將解析后的信息使用作為載體進行注冊已經在中被標記為不建議使用,但是我們分析源碼不影響,因為源碼并未改變,并依舊使用和進行的解析和注冊工作,本篇博客是跟源碼一步步看怎么實現的注冊,源碼為源碼已經在每一行上加了注釋,方便 本文是針對Srping的XMLBeanFactory來進行解析xml并將解析后的信息使用GenericBeanDefinition作為載體進行注冊...
摘要:進一步解析其他所有屬性并統一封裝至類型的實例中。是一個接口,在中存在三種實現以及。通過將配置文件中配置信息轉換為容器的內部表示,并將這些注冊到中。容器的就像是配置信息的內存數據庫,主要是以的形式保存。而代碼的作用就是實現此功能。 前言:繼續前一章。 一、porfile 屬性的使用 如果你使用過SpringBoot, 你一定會知道porfile配置所帶來的方便, 通過配置開發環境還是生產...
閱讀 1380·2021-11-22 09:34
閱讀 2586·2021-11-12 10:36
閱讀 1117·2021-11-11 16:55
閱讀 2329·2020-06-22 14:43
閱讀 1472·2019-08-30 15:55
閱讀 1984·2019-08-30 15:53
閱讀 1769·2019-08-30 10:50
閱讀 1226·2019-08-29 12:15