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

Spring進(jìn)階(十六)之spring生命周期

這篇具有很好參考價(jià)值的文章主要介紹了Spring進(jìn)階(十六)之spring生命周期。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

Bean生命周期

階段1:Bean元信息配置階段

Bean信息定義4種方式

API的方式

XML的方式

properties文件的方式

注解的方式

小結(jié)

階段2:Bean元信息解析階段

Bean元信息的解析主要有3種方式

XML方式解析:XmlBeanDefinitionReader

properties文件定義bean的解析: PropertiesBeanDefinitionReader

注解方式:AnnotatedBeanDefinitionReader

階段3:Spring Bean注冊(cè)階段

Bean注冊(cè)接口:BeanDefinitionRegistry

別名注冊(cè)接口:AliasRegistry

DefaultListableBeanFactory類

階段4:BeanDefinition合并階段

案例

階段5:Bean Class加載階段


Bean生命周期

Spring bean 生命周期可以分為13個(gè)階段:

  1. Bean元信息配置階段
  2. Bean元信息解析階段
  3. 將Bean注冊(cè)到容器中
  4. BeanDefinition合并階段
  5. Bean Class加載階段
  6. Bean實(shí)例化階段(2個(gè)小階段)
    • Bean實(shí)例化前階段
    • Bean實(shí)例化階段
  7. 合并后的BeanDefinition處理
  8. 屬性賦值階段(3個(gè)小階段)
    • Bean實(shí)例化后階段
    • Bean屬性賦值前階段
    • Bean屬性賦值階段
  9. Bean初始化階段(4個(gè)小階段)
    • Bean Aware接口回調(diào)階段
    • Bean初始化前階段
    • Bean初始化階段
    • Bean初始化后階段
  10. 所有單例bean初始化完成后階段
  11. Bean的使用階段
  12. Bean銷毀前階段
  13. Bean銷毀階段

階段1:Bean元信息配置階段

這個(gè)階段主要就是bean信息的定義

Bean信息定義4種方式

  • API的方式
  • Xml文件方式
  • properties文件的方式
  • 注解的方式

API的方式

先來(lái)說(shuō)這種方式,因?yàn)槠渌麕追N方式最終都會(huì)轉(zhuǎn)化為這種方式來(lái)定義bean配置信息。

Spring容器啟動(dòng)的過(guò)程中,會(huì)將Bean解析成Spring內(nèi)部的BeanDefinition結(jié)構(gòu)。 不管是是通過(guò)xml配置文件的標(biāo)簽,還是通過(guò)注解配置的 @Bean ,還是 @Compontent 標(biāo)注的類,還是掃描得到的類等,它最終都會(huì)被解析成一個(gè)BeanDefinition對(duì)象,最后我們的Bean工廠就會(huì)根據(jù)這份Bean的定義信 息,對(duì)bean進(jìn)行實(shí)例化、初始化等等操作。

你可以把BeanDefinition丟給Bean工廠,然后Bean工廠就會(huì)根據(jù)這個(gè)信息幫你生產(chǎn)一個(gè)Bean實(shí)例,拿去使用。 BeanDefinition里面里面包含了bean定義的各種信息,如:bean對(duì)應(yīng)的class、scope、lazy信息、 dependOn信息、autowireCandidate(是否是候選對(duì)象)、primary(是否是主要的候選者)等信息。

BeanDefinition是個(gè)接口,有幾個(gè)實(shí)現(xiàn)類,看一下類圖:

Spring進(jìn)階(十六)之spring生命周期

BeanDefinition接口

bean定義信息的接口,我們下來(lái)看看源碼:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	/**
	 *singleton
	 */
	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

	/**
	 * prototype
	 */
	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;


	
	int ROLE_APPLICATION = 0;

	int ROLE_SUPPORT = 1;

	int ROLE_INFRASTRUCTURE = 2;


	// Modifiable attributes

	/**
	 * 設(shè)置此bean的父bean名稱(對(duì)應(yīng)xml中bean元素的parent屬性)
	 */
	void setParentName(@Nullable String parentName);

	/**
	 * 返回bean定義時(shí)指定的父bean的名稱
	 */
	@Nullable
	String getParentName();

	/**
	 * 指定bean的全路徑類名(對(duì)應(yīng)xml中的bean的class屬性)
	 */
	void setBeanClassName(@Nullable String beanClassName);

	/**
	 * 返回此 bean 定義的當(dāng)前 bean 類名。
     * 請(qǐng)注意,這不一定是運(yùn)行時(shí)使用的實(shí)際類名,以防子定義覆蓋/繼承其父類的類名。此外,這可能只是
     * 調(diào)用工廠方法的類,或者在調(diào)用方法的工廠 bean 引用的情況下它甚至可能是空的。因此,不要認(rèn)為
     * 這是運(yùn)行時(shí)確定的 bean 類型,而只是在單個(gè) bean 定義級(jí)別將其用于解析目的
	 */
	@Nullable
	String getBeanClassName();

	/**
	 * 指定bean的范圍(對(duì)應(yīng)xml中bea定義時(shí)的scope屬性)
	 */
	void setScope(@Nullable String scope);

	/**
	 * 返回bean的范圍
	 */
	@Nullable
	String getScope();

	/**
	 * 設(shè)置是否延遲初始化該bean(對(duì)應(yīng)xml中bean定義時(shí)的lazy屬性)
	 */
	void setLazyInit(boolean lazyInit);

	/**
	 * 返回該bean是否是一個(gè)延遲初始化的bean(只對(duì)單例的bean有效,因?yàn)槎嗬腷ean肯定是使用時(shí)才會(huì)
     * 創(chuàng)建的)
	 */
	boolean isLazyInit();

	/**
	 * 設(shè)置該bean初始化時(shí)需要依賴的bean的名稱,bean工廠會(huì)保證讓這些bean在該bean之前初始化
	 */
	void setDependsOn(@Nullable String... dependsOn);

	/**
	 * 返回此bean依賴的bean的名稱
	 */
	@Nullable
	String[] getDependsOn();

	/**
	 * 設(shè)置此bean是否作為其他bean自動(dòng)注入時(shí)的候選者
	 */
	void setAutowireCandidate(boolean autowireCandidate);

	/**
	 * 返回此bean是否作為其他bean自動(dòng)注入時(shí)的候選者
	 */
	boolean isAutowireCandidate();

	/**
	 * 設(shè)置此bean是否為自動(dòng)注入的主要候選者
	 */
	void setPrimary(boolean primary);

	/**
	 * 返回此bean是否作為自動(dòng)注入的主要候選者
	 */
	boolean isPrimary();

	/**
	 * 指定要使用的工廠bean(如果有)。這是要對(duì)其調(diào)用指定工廠方法的bean的名稱
	 */
	void setFactoryBeanName(@Nullable String factoryBeanName);

	/**
	 * 返回工廠bean名稱(如果有)(對(duì)應(yīng)xml中bean元素的factory-bean屬性)
	 */
	@Nullable
	String getFactoryBeanName();

	/**
	 * 
     * 指定工廠方法(如果有)。此方法將使用構(gòu)造函數(shù)參數(shù)調(diào)用,如果未指定任何參數(shù),則不使用任何參
     * 數(shù)調(diào)用。該方法將在指定的工廠bean(如果有的話)上調(diào)用,或者作為本地bean類上的靜態(tài)方法調(diào)
     * 用。
	 */
	void setFactoryMethodName(@Nullable String factoryMethodName);

	/**
	 * 返回工廠方法名稱(對(duì)應(yīng)xml中bean的factory-method屬性)
	 */
	@Nullable
	String getFactoryMethodName();

	/**
	 * 返回此bean的構(gòu)造函數(shù)參數(shù)值
	 */
	ConstructorArgumentValues getConstructorArgumentValues();

	/**
	 * 是否有構(gòu)造器參數(shù)值設(shè)置信息(對(duì)應(yīng)xml中bean元素的<constructor-arg />子元素)
	 */
	default boolean hasConstructorArgumentValues() {
		return !getConstructorArgumentValues().isEmpty();
	}

	/**
	 * 獲取bean定義時(shí)配置的屬性值設(shè)置信息
	 */
	MutablePropertyValues getPropertyValues();

	/**
	 * 這個(gè)bean定義中是否有屬性設(shè)置信息(對(duì)應(yīng)xml中bean元素的<property />子元素)
	 */
	default boolean hasPropertyValues() {
		return !getPropertyValues().isEmpty();
	}

	/**
	 * 設(shè)置bean初始化方法名稱
	 */
	void setInitMethodName(@Nullable String initMethodName);

	/**
	 * 返回bean初始化方法名稱
	 */
	@Nullable
	String getInitMethodName();

	/**
	 * 設(shè)置bean銷毀方法的名稱
	 */
	void setDestroyMethodName(@Nullable String destroyMethodName);

	/**
	 * 返回bean銷毀方法的名稱
	 */
	@Nullable
	String getDestroyMethodName();

	/**
	 * 為此BeanDefinition設(shè)置角色提示。角色提示為框架和工具提供了特定BeanDefinition的角色和重
     * 要性的指示
	 */
	void setRole(int role);

	/**
	 * 獲取此BeanDefinition的角色提示。角色提示為框架和工具提供了特定BeanDefinition的角色和重
     * 要性的指示
	 */
	int getRole();

	/**
	 * 設(shè)置bean的描述信息
	 */
	void setDescription(@Nullable String description);

	/**
	 * 返回Bean的描述信息
	 */
	@Nullable
	String getDescription();


	// Read-only attributes

	/**
	 * 返回此 bean 定義的可解析類型
	 */
	ResolvableType getResolvableType();

	/**
	 * 是否是單例
	 */
	boolean isSingleton();

	/**
	 * 是否是多例
	 */
	boolean isPrototype();

	/**
	 * 返回此 bean 是否是“抽象的”,即不打算實(shí)例化
	 */
	boolean isAbstract();

	/**
	 * 返回此bean定義來(lái)自的資源的描述(以便在出現(xiàn)錯(cuò)誤時(shí)顯示上下文)
	 */
	@Nullable
	String getResourceDescription();

	/**
	 * 返回原始 BeanDefinition,如果沒有則返回null 
	 */
	@Nullable
	BeanDefinition getOriginatingBeanDefinition();

}

另外,BeanDefinition還實(shí)現(xiàn)了兩個(gè)接口:

  • AttributeAccessor
  • BeanMetadataElement

AttributeAccessor接口:屬性訪問接口

源碼:

public interface AttributeAccessor {

	/**
	 * 設(shè)置 屬性->值 鍵值對(duì)
	 */
	void setAttribute(String name, @Nullable Object value);

	/**
	 * 獲取某個(gè)屬性對(duì)應(yīng)的值
	 */
	@Nullable
	Object getAttribute(String name);

	/**
	 * 移除某個(gè)屬性
	 */
	@Nullable
	Object removeAttribute(String name);

	/**
	 * 是否包含某個(gè)屬性
	 */
	boolean hasAttribute(String name);

	/**
	 * 列出所有屬性
	 */
	String[] attributeNames();

}

這個(gè)接口相當(dāng)于key->value數(shù)據(jù)結(jié)構(gòu)的一種操作,BeanDefinition繼承這個(gè),內(nèi)部實(shí)際上是使用了 LinkedHashMap來(lái)實(shí)現(xiàn)這個(gè)接口中的所有方法,通常我們通過(guò)這些方法來(lái)保存BeanDefinition定義過(guò)程中產(chǎn)生的一些附加信息。

BeanMetaDataElement接口

public interface BeanMetadataElement {

	
	@Nullable
	default Object getSource() {
		return null;
	}

BeanDefinition繼承這個(gè)接口,getSource返回BeanDefinition定義的來(lái)源,比如我們通過(guò)xml定義 BeanDefinition的,此時(shí)getSource就表示定義bean的xml資源;若我們通過(guò)api的方式定義 BeanDefinition,我們可以將source設(shè)置為定義BeanDefinition時(shí)所在的類,出錯(cuò)時(shí),可以根據(jù)這個(gè)來(lái)源方便排錯(cuò)。

RootBeanDefinition類:表示根bean定義信息

通常bean中沒有父bean的就使用這種表示。

ChildBeanDefinition類:表示子bean定義信息

如果需要指定父bean的,可以使用ChildBeanDefinition來(lái)定義子bean的配置信息,里面有個(gè) parentName 屬性,用來(lái)指定父bean的名稱。

GenericBeanDefinition類:通用的bean定義信息

既可以表示沒有父bean的bean配置信息,也可以表示有父bean的子bean配置信息,這個(gè)類里面也有 parentName屬性,用來(lái)指定父bean的名稱。?

ConfigurationClassBeanDefinition類:表示通過(guò)配置類中@Bean方法定義 bean信息?

可以通過(guò)配置類中使用@Bean來(lái)標(biāo)注一些方法,通過(guò)這些方法來(lái)定義bean,這些方法配置的bean信息最后會(huì)轉(zhuǎn)換為ConfigurationClassBeanDefinition類型的對(duì)象。

AnnotatedBeanDefinition接口:表示通過(guò)注解的方式定義的bean信息

里面有個(gè)方法getMetadata()用來(lái)獲取定義這個(gè)bean的類上的所有注解信息。

BeanDefinitionBuilder:構(gòu)建BeanDefinition的工具類?

spring中為了方便操作BeanDefinition,提供了一個(gè)類: BeanDefinitionBuilder ,內(nèi)部提供了很多 靜態(tài)方法,通過(guò)這些方法可以非常方便的組裝BeanDefinition對(duì)象。

案例1:組裝一個(gè)簡(jiǎn)單的bean

public class User {

    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}
    @Test
    void test1() {

        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName());
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        System.out.println(beanDefinition);

    }

運(yùn)行輸出:

Root bean: class [com.example.User]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null

案例2:組裝一個(gè)有屬性的bean?

public class User {

    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}
    @Test
    void test2(){
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName());
        //給該bean的name屬性設(shè)置值
        beanDefinitionBuilder.addPropertyValue("name","張三");
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        System.out.println(beanDefinition);

        System.out.println("---------------------");

        //創(chuàng)建一個(gè)Spring容器
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //將該Bean注冊(cè)到Spring容器中
        beanFactory.registerBeanDefinition("User",beanDefinition);

        //獲取容器中的Bean
        User user = (User) beanFactory.getBean("User");
        System.out.println(user);
    }

運(yùn)行輸出:

Root bean: class [com.example.User]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
---------------------
User{name='張三'}

案例3:組裝一個(gè)有依賴關(guān)系的bean

public class User {

    private String name;

    private Car car;

    public String getName() {
        return name;
    }

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

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", car=" + car +
                '}';
    }
}
public class Car {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                '}';
    }
}
    @Test
    void test3(){
        
        //創(chuàng)建Car對(duì)象,并為其賦值
        BeanDefinitionBuilder beanDefinitionBuilder2 = BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName());
        beanDefinitionBuilder2.addPropertyValue("name","寶馬");
        AbstractBeanDefinition CarBeanDefinition = beanDefinitionBuilder2.getBeanDefinition();

        //創(chuàng)建User對(duì)象,并為其賦值
        BeanDefinitionBuilder beanDefinitionBuilder1 = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName());
        beanDefinitionBuilder1.addPropertyValue("name","張三");
        beanDefinitionBuilder1.addPropertyReference("car","car");//為該bean注入依賴的bean
        AbstractBeanDefinition UserBeanDefinition = beanDefinitionBuilder1.getBeanDefinition();

        //創(chuàng)建Spring容器,將這兩個(gè)Bean注冊(cè)到容器中
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.registerBeanDefinition("user",UserBeanDefinition);
        beanFactory.registerBeanDefinition("car",CarBeanDefinition);

        Car car = (Car) beanFactory.getBean("car");
        System.out.println(car);
        User user = (User) beanFactory.getBean("user");
        System.out.println(user);
    }

運(yùn)行輸出:

Car{name='寶馬'}
User{name='張三', car=Car{name='寶馬'}}

案例4:有父子關(guān)系的bean

public class User {

    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}
@Test
    void test4(){

        //創(chuàng)建一個(gè)bean
        BeanDefinitionBuilder beanDefinitionBuilder1 = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName());
        beanDefinitionBuilder1.addPropertyValue("name","張三");
        AbstractBeanDefinition UserBeanDefinition = beanDefinitionBuilder1.getBeanDefinition();

        //再創(chuàng)建一個(gè)bean,指定該bean的父bean,這樣該bean就擁有了父bean的所有屬性
        BeanDefinitionBuilder beanDefinitionBuilder2 = BeanDefinitionBuilder.childBeanDefinition("user");
        AbstractBeanDefinition UserBeanDefinitionSon = beanDefinitionBuilder2.getBeanDefinition();

        //將兩個(gè)bean都注冊(cè)到容器
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.registerBeanDefinition("user",UserBeanDefinition);
        beanFactory.registerBeanDefinition("userSon",UserBeanDefinitionSon);

        User user = (User) beanFactory.getBean("user");
        System.out.println(user);
        User userSon = (User) beanFactory.getBean("userSon");
        System.out.println(userSon);
    }

運(yùn)行輸出:

User{name='張三'}
User{name='張三'}

注意:

  • 有父子關(guān)系的時(shí)候,我們的 子 創(chuàng)建的不再是rootBeanDifinition對(duì)象了,而是childBeanDefinition對(duì)象,或者genericBeanDefinition對(duì)象,因?yàn)橹挥兴麄儍?nèi)部才有指定父bean的方法
  • 我們知道,一個(gè)bean指定了父bean以后,該bean會(huì)擁有父bean的所有屬性。但是我們?cè)傧胍幌?,子bean擁有了父bean的所有屬性,那屬性值呢?這些屬性會(huì)有值嗎?我們?cè)倏纯瓷厦娴妮敵?,默認(rèn)情況下子bean也擁有了相同的值。又有一個(gè)疑問,那我們可以為子bean的屬性再賦值來(lái)覆蓋之前的值嗎,答案是可以的,如圖:
  • Spring進(jìn)階(十六)之spring生命周期

案例5:通過(guò)api設(shè)置(Map、Set、List)屬性

?主要是用到這幾個(gè)對(duì)象:

  • ManagedList
  • ManagedSet
  • ManagedMap
  • ManagedProperties
  • RuntimeBeanReference(很重要?。。。?/span>
public class Car {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                '}';
    }
}
public class UserObj {

    private String name;
    private Integer salary;
    private Car car;
    private List<String> stringList;
    private List<Car> carList;
    private Set<String> stringSet;
    private Set<Car> carSet;
    private Map<String,String> stringMap;
    private Map<String,Car> stringCarMap;

    public String getName() {
        return name;
    }

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

    public Integer getSalary() {
        return salary;
    }

    public void setSalary(Integer salary) {
        this.salary = salary;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    public List<String> getStringList() {
        return stringList;
    }

    public void setStringList(List<String> stringList) {
        this.stringList = stringList;
    }

    public List<Car> getCarList() {
        return carList;
    }

    public void setCarList(List<Car> carList) {
        this.carList = carList;
    }

    public Set<String> getStringSet() {
        return stringSet;
    }

    public void setStringSet(Set<String> stringSet) {
        this.stringSet = stringSet;
    }

    public Set<Car> getCarSet() {
        return carSet;
    }

    public void setCarSet(Set<Car> carSet) {
        this.carSet = carSet;
    }

    public Map<String, String> getStringMap() {
        return stringMap;
    }

    public void setStringMap(Map<String, String> stringMap) {
        this.stringMap = stringMap;
    }

    public Map<String, Car> getStringCarMap() {
        return stringCarMap;
    }

    public void setStringCarMap(Map<String, Car> stringCarMap) {
        this.stringCarMap = stringCarMap;
    }

    @Override
    public String toString() {
        return "UserObj{" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                ", car=" + car +
                ", stringList=" + stringList +
                ", carList=" + carList +
                ", stringSet=" + stringSet +
                ", carSet=" + carSet +
                ", stringMap=" + stringMap +
                ", stringCarMap=" + stringCarMap +
                '}';
    }
}
    @Test
    void test5(){

        BeanDefinitionBuilder beanDefinitionBuilder1 = BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName());
        beanDefinitionBuilder1.addPropertyValue("name","奧迪");
        AbstractBeanDefinition beanDefinition1 = beanDefinitionBuilder1.getBeanDefinition();

        BeanDefinitionBuilder beanDefinitionBuilder2 = BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName());
        beanDefinitionBuilder2.addPropertyValue("name","寶馬");
        AbstractBeanDefinition beanDefinition2 = beanDefinitionBuilder2.getBeanDefinition();

        ManagedList<String> stringList = new ManagedList<>();
        stringList.addAll(Arrays.asList("test1","test2","test3"));

        ManagedList<RuntimeBeanReference> carList = new ManagedList<>();
        carList.add(new RuntimeBeanReference("car1"));
        carList.add(new RuntimeBeanReference("car2"));

        ManagedSet<String> stringSet = new ManagedSet<>();
        stringSet.addAll(Arrays.asList("test1","test2","test3"));

        ManagedSet<RuntimeBeanReference> carSet = new ManagedSet<>();
        carSet.add(new RuntimeBeanReference("car1"));
        carSet.add(new RuntimeBeanReference("car2"));

        ManagedMap<String, String> stringMap = new ManagedMap<>();
        stringMap.put("測(cè)試1","test1");
        stringMap.put("測(cè)試2","test2");
        stringMap.put("測(cè)試3","test3");

        ManagedMap<String, RuntimeBeanReference> stringCarMap = new ManagedMap<>();
        stringCarMap.put("car1",new RuntimeBeanReference("car1"));
        stringCarMap.put("car2",new RuntimeBeanReference("car2"));

        BeanDefinitionBuilder beanDefinitionBuilder3 = BeanDefinitionBuilder.rootBeanDefinition(UserObj.class.getName());
        beanDefinitionBuilder3.addPropertyValue("name","張三");
        beanDefinitionBuilder3.addPropertyValue("salary",50000);
        beanDefinitionBuilder3.addPropertyValue("stringList",stringList);
        beanDefinitionBuilder3.addPropertyValue("carList",carList);
        beanDefinitionBuilder3.addPropertyValue("stringSet",stringSet);
        beanDefinitionBuilder3.addPropertyValue("carSet",carSet);
        beanDefinitionBuilder3.addPropertyValue("stringMap",stringMap);
        beanDefinitionBuilder3.addPropertyValue("stringCarMap",stringCarMap);
        AbstractBeanDefinition beanDefinition3 = beanDefinitionBuilder3.getBeanDefinition();

        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.registerBeanDefinition("car1",beanDefinition1);
        factory.registerBeanDefinition("car2",beanDefinition2);
        factory.registerBeanDefinition("UserObj",beanDefinition3);

        System.out.println(factory.getBean("car1"));
        System.out.println(factory.getBean("car2"));
        System.out.println(factory.getBean("UserObj"));

    }

運(yùn)行輸出:

Car{name='奧迪'}
Car{name='寶馬'}
UserObj{name='張三', salary=50000, car=null, stringList=[test1, test2, test3], carList=[Car{name='奧迪'}, Car{name='寶馬'}], stringSet=[test1, test2, test3], carSet=[Car{name='奧迪'}, Car{name='寶馬'}], stringMap={測(cè)試1=test1, 測(cè)試2=test2, 測(cè)試3=test3}, stringCarMap={car1=Car{name='奧迪'}, car2=Car{name='寶馬'}}}

XML的方式

我們一開始學(xué)spring的時(shí)候使用的就是這種方式,已經(jīng)很熟悉了,這里不做贅述

properties文件的方式

這種方式很陌生,將bean定義信息放在properties文件中,然后通過(guò)解析器將配置信息解析為BeanDefinition對(duì)象。

employee.(class)=MyClass // 等同于:<bean class="MyClass" />
employee.(abstract)=true // 等同于:<bean abstract="true" />
employee.group=Insurance // 為屬性設(shè)置值,等同于:<property name="group" value="Insurance" />
employee.usesDialUp=false // 為employee這個(gè)bean中的usesDialUp屬性設(shè)置值,等同于:<property name="usesDialUp" value="false" />
salesrep.(parent)=employee // 定義了一個(gè)id為salesrep的bean,指定父bean為employee,等同于:<bean id="salesrep" parent="employee" />
salesrep.(lazy-init)=true // 設(shè)置延遲初始化,等同于:<bean lazy-init="true" />
salesrep.manager(ref)=tony // 設(shè)置這個(gè)bean的manager屬性值,是另外一個(gè)bean,名稱為tony,等同于:<property name="manager" ref="tony" />
salesrep.department=Sales // 等同于:<property name="department" value="Sales" />
techie.(parent)=employee // 定義了一個(gè)id為techie的bean,指定父bean為employee,等同于:<bean id="techie" parent="employee" />
techie.(scope)=prototype // 設(shè)置bean的作用域,等同于<bean scope="prototype" />
techie.manager(ref)=jeff // 等同于:<property name="manager" ref="jeff" />
techie.department=Engineering // <property name="department" value="Engineering" />
techie.usesDialUp=true // <property name="usesDialUp" value="true" />
ceo.$0(ref)=secretary // 設(shè)置構(gòu)造函數(shù)第1個(gè)參數(shù)值,等同于:<constructor-arg index="0" ref="secretary" />
ceo.$1=1000000 // 設(shè)置構(gòu)造函數(shù)第2個(gè)參數(shù)值,等同于:<constructor-arg index="1" value="1000000" />

注解的方式

對(duì)于注解的方式注冊(cè)bean的話,常見的就是@Component和@Bean了,這里也不做贅述了。

小結(jié)

不管是那一種方式注冊(cè)bean,最終都是會(huì)解析成一個(gè)BeanDefinition對(duì)象。

階段2:Bean元信息解析階段

Bean元信息的解析就是將各種方式定義的bean配置信息解析為BeanDefinition對(duì)象

Bean元信息的解析主要有3種方式

  1. 解析xml方式定義的bean
  2. 解析properties文件定義的bean
  3. 解析注解方式定義的bean

XML方式解析:XmlBeanDefinitionReader

spring中提供了一個(gè)類 XmlBeanDefinitionReader ,將xml中定義的bean解析為BeanDefinition對(duì) 象。?

案例:

public class Car {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                '}';
    }
}
public class User {

    private String name;

    private Car car;

    public String getName() {
        return name;
    }

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

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

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

}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="car" class="com.example.Car">
        <property name="name" value="寶馬"></property>
    </bean>

    <bean id="car1" class="com.example.Car">
        <property name="name" value="奧迪"></property>
    </bean>

    <bean id="car2" parent="car1"></bean>

    <bean id="user" class="com.example.User">
        <property name="name" value="張三"></property>
        <property name="car" ref="car2"></property>
    </bean>

</beans>
    @Test
    public void test1(){

        //創(chuàng)建一個(gè)spring容器
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

        //定義一個(gè)xml方式的bean的讀取器,需要傳入一個(gè)bean的注冊(cè)器
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);

        //根據(jù)xml文件的位置解析定義的bean,并將其注冊(cè)到我們上面指定的spring容器中
        String location="applicationContext.xml";
        xmlBeanDefinitionReader.loadBeanDefinitions(location);

        for (String beanName:factory.getBeanDefinitionNames()){
            System.out.println(beanName+"===>"+factory.getBean(beanName));
        }
    }

運(yùn)行輸出:

car===>Car{name='寶馬'}
car1===>Car{name='奧迪'}
car2===>Car{name='奧迪'}
user===>User{name='張三', car=Car{name='奧迪'}}

properties文件定義bean的解析: PropertiesBeanDefinitionReader

spring中提供了一個(gè)叫PropertiesBeanDefinitionReader的類,將properties中定義的bean解析為一個(gè)BeanDefinition對(duì)象

案例:

car.(class)=com.example.Car
car.name=奧迪
car1.(class)=com.example.Car
car1.name=寶馬
car2.(parent)=car1
user.(class)=com.example.User
user.name=張三
user.car(ref)=car
    @Test
    public void test2(){

        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        PropertiesBeanDefinitionReader propertiesBeanDefinitionReader = new PropertiesBeanDefinitionReader(beanFactory);

        String location="applicationContext.properties";
        propertiesBeanDefinitionReader.loadBeanDefinitions(location);

        for (String beanName:beanFactory.getBeanDefinitionNames()){
            System.out.println(beanName+"===>"+beanFactory.getBean(beanName));
        }
    }

運(yùn)行輸出:

user===>User{name='張三', car=Car{name='寶馬'}}
car1===>Car{name='奧迪'}
car===>Car{name='寶馬'}
car2===>Car{name='寶馬'}

其實(shí)解析的方式也和xml差不多,只是換成了對(duì)應(yīng)的類來(lái)解析bean而已。

注解方式:AnnotatedBeanDefinitionReader

@Primary
public class Car {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                '}';
    }
}
@Lazy
public class User {


    @Autowired
    private Car car;

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "User{" +
                "car=" + car +
                '}';
    }
}
    @Test
    public void test3(){

        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

        AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(factory);

        annotatedBeanDefinitionReader.register(Car.class,User.class);

        for (String beanName:factory.getBeanDefinitionNames()){
            System.out.println(beanName+"===>"+ factory.getBean(beanName));
        }
    }

運(yùn)行輸出:

car===>Car{name='null'}
user===>User{car=null}

注意:

  1. 我們所說(shuō)的注解的解析方式,用到了AnnotatedBeanDefinitionReader類來(lái)解析
  2. 千萬(wàn)千萬(wàn)別理解錯(cuò)了,并不是說(shuō)要在類上加上@Component注解,才能通過(guò)AnnotatedBeanDefinitionReader類來(lái)解析這個(gè)類。其實(shí)@Component注解就沒啥用,相當(dāng)于一個(gè)標(biāo)識(shí)符,就是默認(rèn)情況下看到@Component標(biāo)注的注解以后,spring就認(rèn)為我們要解析這個(gè)類為一個(gè)bean并放到spring容器中
  3. 可以看到案例里面,注解和xml或者properties方式的解析略有不同,xml或者properties方式是用到了一個(gè)叫l(wèi)oadBeanDefinitions()的方法,然后傳入文件所在位置。而注解解析的方式是用到了register()方法,傳入的參數(shù)是需要的類,且是一個(gè)可變參數(shù)。
  4. 根據(jù)輸出,我們可以看到user里面的car為空,為什么?。棵髅魑覀円呀?jīng)用@Autowired注入了啊,這個(gè)疑問后面再來(lái)解答

階段3:Spring Bean注冊(cè)階段

bean注冊(cè)階段需要用到一個(gè)非常重要的接口:BeanDefinitionRegistry?

Bean注冊(cè)接口:BeanDefinitionRegistry

該接口中定義了常用的操作bean的方法

先來(lái)看看這個(gè)接口的源碼:

public interface BeanDefinitionRegistry extends AliasRegistry {

	/**
	 * 注冊(cè)一個(gè)新的beanDefinition
	 */
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException;

	/**
	 * 從容器中移除指定名稱的bean
	 */
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * 返回該bean的定義信息
	 */
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * 返回容器中是否含有該bean
	 */
	boolean containsBeanDefinition(String beanName);

	/**
	 * 返回容器中bean的名稱列表
	 */
	String[] getBeanDefinitionNames();

	/**
	 * 返回容器中bean的數(shù)量
	 */
	int getBeanDefinitionCount();

	/**
	 * 返回該bean是否被使用。(beanName可以時(shí)名稱或者別名)
	 */
	boolean isBeanNameInUse(String beanName);

}

別名注冊(cè)接口:AliasRegistry

BeanDefinitionRegistry 接口繼承了 AliasRegistry 接口,這個(gè)接口中定義了操作bean別名的一些 方法,看一下其源碼:

public interface AliasRegistry {

	/**
	 * 為該bean創(chuàng)建一個(gè)別名
	 */
	void registerAlias(String name, String alias);

	/**
	 * 移除該別名
	 */
	void removeAlias(String alias);

	/**
	 * 返回該別名是否使用
	 */
	boolean isAlias(String name);

	/**
	 * 返回別名列表
	 */
	String[] getAliases(String name);

}

DefaultListableBeanFactory類

該類是BeanDefinitionRegistry的實(shí)現(xiàn)類

我們打開源碼可以看到BeanDefinitionRegistry有很多實(shí)現(xiàn)類,那為什么特別提到了其中的DefaultListableBeanFactory實(shí)現(xiàn)類你,因?yàn)槠渌鼘?shí)現(xiàn)類的內(nèi)部都是轉(zhuǎn)發(fā)給DefaultListableBeanFactory進(jìn)行處理的,所以真正的實(shí)現(xiàn)BeanDefinitionRegistry這個(gè)接口的類是DefaultListableBeanFactory

階段4:BeanDefinition合并階段

可能我們定義bean的時(shí)候有父子bean關(guān)系,此時(shí)子BeanDefinition中的信息是不完整的,比如設(shè)置屬性的時(shí)候配置在父BeanDefinition中,此時(shí)子BeanDefinition中是沒有這些信息的,或者子bean和父bean中都設(shè)置了屬性,那我們此時(shí)的子beanDefinition肯定是不完整的,需要將子bean的 BeanDefinition和父bean的BeanDefinition進(jìn)行合并,如果有沖突的屬性,子bean的屬性會(huì)覆蓋父bean的,經(jīng)過(guò)上面的操作最終就會(huì)得到一個(gè) RootBeanDefinition ,合并之后得到的 RootBeanDefinition 包含bean定義的所有信息,包含了從父bean中繼繼承過(guò)來(lái)的所有信息,后續(xù)bean的所有創(chuàng)建工作就是依靠合并之后BeanDefinition來(lái)進(jìn)行的。 合并BeanDefinition會(huì)使用下面這個(gè)方法:

org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefin ition

bean定義可能存在多級(jí)父子關(guān)系,合并的時(shí)候進(jìn)進(jìn)行遞歸合并,最終得到一個(gè)包含完整信息的 RootBeanDefinition

案例

public class Course {

    private String courseName;

    private String description;

    public String getCourseName() {
        return courseName;
    }

    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "Course{" +
                "courseName='" + courseName + '\'' +
                ", description='" + description + '\'' +
                '}';
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="course" class="com.example.Course"></bean>

    <bean id="course1" parent="course">
        <property name="courseName" value="java"></property>
        <property name="description" value="java核心技術(shù)課程"></property>
    </bean>

    <bean id="course2" parent="course1">
        <property name="description" value="javaWeb課程"></property>
    </bean>

</beans>
public class mergeBeanDefinitionTest {
    @Test
    public void test(){

        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        String location="applicationContext.xml";
        xmlBeanDefinitionReader.loadBeanDefinitions(location);

        for (String beanName:beanFactory.getBeanDefinitionNames()){
            System.out.println("-------------------------");
            System.out.println(beanName);

            System.out.println("合并前");
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
            System.out.println(beanDefinition);
            for (PropertyValue property:beanDefinition.getPropertyValues()){
                System.out.println(property.getName()+"====>"+property.getValue());
            }
            //調(diào)用該方法將父子beanDefinition合并,才能讓子的beanDefinition完整
            BeanDefinition mergedBeanDefinition = beanFactory.getMergedBeanDefinition(beanName);

            System.out.println("合并后");
            System.out.println(mergedBeanDefinition);
            for (PropertyValue property:mergedBeanDefinition.getPropertyValues()){
                System.out.println(property.getName()+"====>"+property.getValue());
            }
            System.out.println("-------------------------");
        }
    }
}

?運(yùn)行輸出:

-------------------------
course
合并前
Generic bean: class [com.example.Course]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]
合并后
Root bean: class [com.example.Course]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]
-------------------------
-------------------------
course1
合并前
Generic bean with parent 'course': class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]
courseName====>TypedStringValue: value [java], target type [null]
description====>TypedStringValue: value [java核心技術(shù)課程], target type [null]

合并后
Root bean: class [com.example.Course]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]
courseName====>TypedStringValue: value [java], target type [null]
description====>TypedStringValue: value [java核心技術(shù)課程], target type [null]

-------------------------
-------------------------
course2
合并前
Generic bean with parent 'course1': class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]
description====>TypedStringValue: value [javaWeb課程], target type [null]

合并后
Root bean: class [com.example.Course]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]
courseName====>TypedStringValue: value [java], target type [null]
description====>TypedStringValue: value [javaWeb課程], target type [null]

-------------------------

重點(diǎn)觀察彩色字體部分, course1繼承了course,但course本身就沒有屬性,綠色部分的屬性本身就是course1自己的,所有合并前合并后都有這些屬性并不奇怪。我們?cè)倏纯碿ours2的黃色部分,course2是繼承了course1的,course2本身有一個(gè)description屬性,所以合并之前course2只有一個(gè)description屬性并不奇怪,但是我們看看合并之后,course2有了courseName屬性了,這就是從course1繼承過(guò)來(lái)的屬性,這說(shuō)明了什么?說(shuō)明就是通過(guò)我們調(diào)用了getMergeBeanDefinition()以后,子bean和父bean合并,從而讓我們的子bean擁有完整的beanDefinition信息,驗(yàn)證了上面的說(shuō)法!!!還有一點(diǎn),如果我們?cè)诤喜⑷绻蛴∫幌抡{(diào)用getMergeBeanDefinition方法返回的對(duì)象,就會(huì)發(fā)現(xiàn)該BeanDefinition對(duì)象的類型已經(jīng)從GenericBeanDefinition變?yōu)镽ootBeanDefinition類型了,并且以后操作都是又這個(gè)完整的RootBeanDefinition來(lái)完成。

階段5:Bean Class加載階段

這個(gè)階段就是將bean的class名稱轉(zhuǎn)換為Class類型的對(duì)象

BeanDefinition中有個(gè)Object類型的字段:beanClass

private volatile Object beanClass;

用來(lái)表示bean的class對(duì)象,通常這個(gè)字段的值有2種類型,一種是bean對(duì)應(yīng)的Class類型的對(duì)象,另一 種是bean對(duì)應(yīng)的Class的完整類名,第一種情況不需要解析,第二種情況:即這個(gè)字段是bean的類名的時(shí)候,就需要通過(guò)類加載器將其轉(zhuǎn)換為一個(gè)Class對(duì)象。 此時(shí)會(huì)對(duì)階段4中合并產(chǎn)生的 RootBeanDefinition 中的 beanClass 進(jìn)行解析,將bean的類名轉(zhuǎn)換為 Class對(duì)象 ,然后賦值給 beanClass 字段。?

源碼位置:

org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass

然后就開始進(jìn)入下面的實(shí)例化這個(gè)對(duì)象的階段了。我們下篇文章繼續(xù)來(lái)看?。?!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-435119.html

到了這里,關(guān)于Spring進(jìn)階(十六)之spring生命周期的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • spring框架-概述(spring特性、生命周期)(一)

    spring框架-概述(spring特性、生命周期)(一)

    Spring框架是一個(gè)開放源代碼的J2EE應(yīng)用程序框架,由Rod Johnson發(fā)起,是針對(duì)bean的生命周期進(jìn)行管理的輕量級(jí)容器 ,是為了解決企業(yè)級(jí)編程開發(fā)中的復(fù)雜性,實(shí)現(xiàn)敏捷開發(fā)的應(yīng)用型框架 IOC: (Inverse of Control ):一種思想 (容器幫我們創(chuàng)建對(duì)象并且管理和控制 ) 反轉(zhuǎn)后不再由自己

    2024年02月10日
    瀏覽(23)
  • Spring Bean的生命周期 -- Spring入門(三)

    Spring Bean的生命周期 -- Spring入門(三)

    為了鞏固所學(xué)的知識(shí),作者嘗試著開始發(fā)布一些學(xué)習(xí)筆記類的博客,方便日后回顧。當(dāng)然,如果能幫到一些萌新進(jìn)行新技術(shù)的學(xué)習(xí)那也是極好的。作者菜菜一枚,文章中如果有記錄錯(cuò)誤,歡迎讀者朋友們批評(píng)指正。 (博客的參考源碼以及可以在我主頁(yè)的資源里找到,如果在學(xué)

    2024年02月15日
    瀏覽(25)
  • 【Spring】Spring之Bean生命周期源碼解析

    什么是bean的生命周期 是指bean在spring中是如何生成,如何銷毀的; spring創(chuàng)建對(duì)象的過(guò)程,就是IOC(控制反轉(zhuǎn))的過(guò)程; JFR Java Flight Record,java飛行記錄,類似于飛機(jī)的黑匣子,是JVM內(nèi)置的基于事件的JDK監(jiān)控記錄框架,主要用于問題定位和持續(xù)監(jiān)控; 入口代碼: Spring啟動(dòng)的時(shí)

    2024年02月15日
    瀏覽(23)
  • 【Spring】—— bean生命周期

    1、初始化容器 1)創(chuàng)建對(duì)象(分配內(nèi)存) 2)執(zhí)行構(gòu)造方法 3)執(zhí)行屬性注入(set操作) 4)執(zhí)行bean初始化方法 2、使用bean 1)執(zhí)行業(yè)務(wù)操作 3、關(guān)閉/銷毀容器 1)執(zhí)行bean銷毀方法

    2024年02月02日
    瀏覽(28)
  • Spring bean 生命周期

    Spring bean 生命周期

    在互聯(lián)網(wǎng)領(lǐng)域中,Spring框架扮演著重要的角色。作為一個(gè)開源的Java應(yīng)用程序開發(fā)框架,Spring提供了一種靈活而強(qiáng)大的方式來(lái)構(gòu)建可擴(kuò)展的應(yīng)用程序。Spring框架中的一個(gè)重要概念是Bean,它是Spring應(yīng)用程序的基本構(gòu)建塊之一。了解Spring Bean的生命周期對(duì)于充分利用Spring框架的功能

    2024年02月11日
    瀏覽(26)
  • Spring:Bean生命周期

    Spring:Bean生命周期

    Bean 生命周期 是 bean 對(duì)象從創(chuàng)建到銷毀的整個(gè)過(guò)程。 簡(jiǎn)單的 Bean 生命周期的過(guò)程: 1.實(shí)例化(調(diào)用構(gòu)造方法對(duì) bean 進(jìn)行實(shí)例化) 2.依賴注入(調(diào)用 set 方法對(duì) bean 進(jìn)行賦值) 3.初始化(手動(dòng)配置 xml 文件中 bean 標(biāo)簽的 init-method 屬性值,來(lái)指定調(diào)用對(duì)應(yīng)的初始化方法) 4.使用

    2024年02月13日
    瀏覽(27)
  • 淺析Spring生命周期

    淺析Spring生命周期

    Spring框架是一個(gè)非常流行的Java企業(yè)級(jí)應(yīng)用程序框架,已經(jīng)成為許多生產(chǎn)環(huán)境中的首選技術(shù)。它提供了一種便捷的方法來(lái)幫助開發(fā)人員構(gòu)建可擴(kuò)展和模塊化的企業(yè)級(jí)應(yīng)用程序。在Spring框架中,Bean生命周期是非常重要的一部分,它負(fù)責(zé)Bean的創(chuàng)建和銷毀。 Spring框架中Bean的完整生

    2024年02月08日
    瀏覽(14)
  • 【Spring】Bean的作用域與生命周期詳情:請(qǐng)簡(jiǎn)述Spring的執(zhí)行流程并分析Bean的生命周期?

    【Spring】Bean的作用域與生命周期詳情:請(qǐng)簡(jiǎn)述Spring的執(zhí)行流程并分析Bean的生命周期?

    ?我們都知道,Spring框架為開發(fā)人員提供了很多便捷,這使得開發(fā)人員能夠更加專注于應(yīng)用程序的核心業(yè)務(wù)邏輯,而不需要花費(fèi)大量時(shí)間和精力在技術(shù)細(xì)節(jié)上。作為一個(gè)包含眾多工具方法的IoC容器,存取JavaBean是其極為重要的一個(gè)環(huán)節(jié)。本文就對(duì)Spring中的Bean的作用域和生命周

    2024年02月12日
    瀏覽(27)
  • Spring Bean的生命周期

    Spring Bean的生命周期

    Bean生命周期的整個(gè)執(zhí)行過(guò)程描述如下: 1、根據(jù)配置情況調(diào)用Bean構(gòu)造方法或工廠方法實(shí)例化 Bean。 2、利用依賴注入完成Bean中所有屬性值的配置注入。 3、如果Bean 實(shí)現(xiàn)了BeanNameAware 接口,則 Spring調(diào)用Bean的setBeanName()方法傳入當(dāng)前Bean的id值。 4、如果Bean實(shí)現(xiàn)了BeanFactoryAware 接口

    2023年04月22日
    瀏覽(35)
  • Spring -- Bean的生命周期

    Spring -- Bean的生命周期

    Spring容器在進(jìn)行實(shí)例化時(shí),會(huì)將xml配置的bean的信息封裝成一個(gè)BeanDefinition對(duì)象,Spring根據(jù)BeanDefinition來(lái)創(chuàng)建Bean對(duì)象,里面有很多的屬性用來(lái)描述Bean? ?BeanDefinition 中幾個(gè)重要方法如下 beanClassName:bean 的類名 initMethodName:初始化方法名稱 properryValues:bean 的屬性值 scope:作用域

    2024年02月15日
    瀏覽(35)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包