Spring bean的創建方式 作用域 生命週期

創建對象的三種方式:

1、採用默認的構造函數創建
2、採用靜態工廠方法

  • 1、寫一個靜態工廠方法類
public class HelloWorldFactory {
	public static HelloWorld getInstance(){
		return new HelloWorld();
 	}
}
  • 2、在spring的配置文件中進行聲明
<bean id="helloWorld2" class="com.itheima05.spring.bean.HelloWorldFactory" factory-method="getInstance"></bean>

告訴spring容器利用HelloWorldFactory類中的getInsatance靜態方法產生對象
但是具體的對象的創建的過程是由程序員來完成的

3、實例工廠方法

  • 1、寫一個實例工廠類
 public class HelloWorldFactory {
     public HelloWorld getInstance(){
        return new HelloWorld();
     }
  }
  • 2、在spring的配置文件中

1)spring容器爲HelloWorldFactory2創建對象

 <bean id="helloWorld3" class="com.itheima05.spring.bean.HelloWorldFactory2"></bean>

2)告訴spring容器,利用helloWorld3對象調用getInstance方法

 <bean id="helloWorldFactory" factory-bean="helloWorld3" factory-method="getInstance"></bean>

創建對象的時機
1、在默認的情況下,在spring容器啓動的時候創建對象
在spring配置文件中,只要根據以上的三種方式的其中一種配置了,spring容器就會創建對象
好處:
spring容器和web容器整合的時候,當web容器啓動的時候就可以初始化spring容器了,如果這個時候spring容器內部有錯誤,則直接會報錯
缺點:
如果該bean中存放着大量的數據,而且數據的初始化發生在創建對象的時候,這個時候,數據會過早的駐留在內存中
2、如果在spring的配置文件中一個bean的配置中有lazy-init=“true”,那麼該bean在調用getBean方法時創建對象
缺點:不能過早的發現錯誤
好處:按照需求加載數據(什麼時候要什麼時候加載)

作用域scope配置項

作用域限定了Spring Bean的作用範圍,在Spring配置文件定義Bean時,通過聲明scope配置項,可以靈活定義Bean的作用範圍。例如,當你希望每次IOC容器返回的Bean是同一個實例時,可以設置scope爲singleton;當你希望每次IOC容器返回的Bean實例是一個新的實例時,可以設置scope爲prototype。

scope配置項有5個屬性,用於描述不同的作用域。

① singleton

使用該屬性定義Bean時,IOC容器僅創建一個Bean實例,IOC容器每次返回的是同一個Bean實例。

② prototype

使用該屬性定義Bean時,IOC容器可以創建多個Bean實例,每次返回的都是一個新的實例。

③ request

該屬性僅對HTTP請求產生作用,使用該屬性定義Bean時,每次HTTP請求都會創建一個新的Bean,適用於WebApplicationContext環境。

④ session

該屬性僅用於HTTP Session,同一個Session共享一個Bean實例。不同Session使用不同的實例。

⑤ global-session

該屬性僅用於HTTP Session,同session作用域不同的是,所有的Session共享一個Bean實例。

生命週期

在這裏插入圖片描述

spring 容器中的bean的完整生命週期一共分爲十一步完成。

1.bean對象的實例化

2.封裝屬性,也就是設置properties中的屬性值

3.如果bean實現了BeanNameAware,則執行setBeanName方法,也就是bean中的id值

4.如果實現BeanFactoryAware或者ApplicationContextAware ,需要設置setBeanFactory或者上下文對象setApplicationContext

5.如果存在類實現BeanPostProcessor後處理bean,執行postProcessBeforeInitialization,可以在初始化之前執行一些方法

6.如果bean實現了InitializingBean,則執行afterPropertiesSet,執行屬性設置之後的操作

7.調用 < bean init-method=""> 執行指定的初始化方法

8.如果存在類實現BeanPostProcessor則執行postProcessAfterInitialization,執行初始化之後的操作

9.執行自身的業務方法

10.如果bean實現了DisposableBean,則執行spring的的銷燬方法

11.調用< bean destory-method="">執行自定義的銷燬方法。

第五步和第八步可以結合aop,在初始化執行之前或者執行之後執行一些操作。

以上就是springbean的完整生命週期

代碼

public class Man implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
    private String name;

    public Man() {
        System.out.println("第一步:實例化類");
    }

    public void setName(String name) {
        System.out.println("第二步:設置屬性");
        this.name = name;
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("第三步:設置bean的名稱也就是spring容器中的名稱,也就是id值" + name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("第四步:瞭解工廠信息ApplicationContext");
    }
    //第五步執行初始化之前執行的方法


    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("第六步:屬性設置後執行的方法");
    }

    public void setup() {
        System.out.println("第七步:執行自己配置的初始化方法");
    }
    //第八步執行初始化之後執行的方法
    public void run() {
        System.out.println("第九步:執行自身的業務方法");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("第十步:執行spring的銷燬方法");
    }

    public void destory() {
        System.out.println("第十一步:執行自己配置的銷燬方法");
    }


}

指定的類實現了BeanPostProcessor
public class MyBeanPostProcess implements BeanPostProcessor {

    //後處理bean,最重要的兩步
    @Override
    public Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {
        System.out.println("第五步:初始化之前執行的方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
        System.out.println("第八步:執行初始化之後的方法");
        return bean;
    }
}

applicationContext.xml中的配置
<bean id="man" class="com.itheima.ioc.springBeanlife.Man" init-method="setup" destroy-method="destory">
    <property name="name" value="張三"/>
</bean>
<bean class="com.itheima.ioc.springBeanlife.MyBeanPostProcess"/>


測試
@Test
public  void beanlifeTest(){
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    Man man=(Man)context.getBean("man");
    man.run();
    context.close();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章