Spring IoC之Bean管理

        Spring對Bean的管理包括Bean的初始化、Bean的注入、Bean的生命週期管理、Bean的做用域管理....等。Spring提供了三種實例化Bean的方式:使用類構造器、使用靜態工廠類、使用工廠類;Spring經過依賴注入(DI)解耦對象的依賴關係,並提供了構造注入、設值注入兩種注入方式;Spring提供「singleton」和「prototype」兩種基本做用域,另外提供「request」、「session」、「global session」三種web做用域,Spring還容許用戶定製本身的做用域。java

Bean的初始化

spring提供了三種實例化Bean的方式:使用類構造器、使用靜態工廠類、使用工廠類。web

① 使用類構造器實例化Bean, IoC容器使用默認空構造器   spring

 <bean id="helloBean1" class="com.yang.service.impl.HelloBean"/>

② 使用靜態工廠方法實例化Bean
編程

<bean id="helloBean2" class="com.yang.factory.HelloBeanStaticFactory" factory-method="createHelloBean"/>
public class HelloBeanStaticFactory {  
    public static Hello createHelloBean() {  
        return new HelloBean();  
    }  
}

③ 使用實例工廠方法實例化Bean
緩存

<bean id="instanceFactory" class="com.yang.factory.HelloBeanInstanceFactory"/> 
<bean id="helloBean3" factory-bean="instanceFactory" factory-method="createHelloBean"/>
public class HelloBeanInstanceFactory {  
    public Hello createHelloBean() {  
        return new HelloBean();  
    }  
}

依賴注入(DI)

   依賴注入的原理很簡單,即利用Java的反射機制並充當工廠的角色完成對象的裝配和注入。 session

    Spring提供了兩種依賴注入的方式:構造函數注入和設值注入。(有的地方將接口注入也看成一種注入方式,我以爲接口注入只是接口編程思想的體現,不能算做注入方式,因此此處不做爲一種方式。)函數

①  使用構造函數注入:post

<bean id="personDao" class="com.yang.dao.impl.PersonDaoImpl" /> 
<bean id="personService" class="com.yang.service.impl.PersonServiceImpl">
       <constructor-arg index="0" ref="personDao" />
</bean>
public class PersonServiceImpl implements PersonService {  
    private PersonDao personDao;  
    public PersonServiceImpl(PersonDao personDao) {  
        this.personDao = personDao;  
    }  
    public void save() {  
        personDao.save();  
    }  
}

② setter方法注入:  注入對象, 基本屬性, 集合this

<bean id="personDao" class="com.zdp.dao.impl.PersonDaoImpl" />  
    <bean id="personService" class="com.zdp.service.impl.PersonServiceImpl">  
        <!--   
            <property name="personDao">   
                <ref bean="personDao"/>   
            </property>   
        -->  
        <property name="personDao" ref="personDao" />  
        <property name="name" value="zhangsan" />  
        <property name="id" value="123" />  
        <property name="sets">  
            <set>  
                <value>1</value>  
                <value>2</value>  
            </set>  
        </property>  
        <property name="lists">  
            <list>  
                <value>1</value>  
                <value>2</value>  
                <value>3</value>  
            </list>  
        </property>  
        <property name="maps">  
            <map>  
                <entry key="1" value="1"></entry>  
                <entry key="2" value="2"></entry>  
                <entry key="3" value="3"></entry>  
                <entry key="4" value="4"></entry>  
            </map>  
        </property>  
    </bean>
public class PersonServiceImpl implements PersonService {  
    private PersonDao personDao;  
    private String name;  
    private Integer id;  
    private Set<String> sets;  
    private List<String> lists;  
    private Map<String, String> maps;  
  
    // 省略get set方法  
  
    public void save() {  
        System.out.println("id: " + id + ", name: " + name);  
        System.out.println("sets: " + sets.size() + ", lists: " + lists.size() + ", maps: " + maps.size());  
        personDao.save();  
    }  
}


Bean做用域

Spring提供「singleton」和「prototype」兩種基本做用域,另外提供「request」、「session」、「global session」三種web做用域;Spring還容許用戶定製本身的做用域。spring的默認做用域是singletonspa

  • singleton:指「singleton」做用域的Bean只會在每一個Spring IoC容器中存在一個實例,並且其完整生命週期徹底由Spring容器管理。對於全部獲取該Bean的操做Spring容器將只返回同一個Bean。

  • prototype:即原型,指每次向Spring容器請求獲取Bean都返回一個全新的Bean,相對於「singleton」來講就是不緩存Bean,每次都是一個根據Bean定義建立的全新Bean。

  • request做用域:表示每一個請求須要容器建立一個全新Bean。好比提交表單的數據必須是對每次請求新建一個Bean來保持這些表單數據,請求結束釋放這些數據。

  • session做用域:表示每一個會話須要容器建立一個全新Bean。好比對於每一個用戶通常會有一個會話,該用戶的用戶信息須要存儲到會話中,此時能夠將該Bean配置爲web做用域。

  • globalSession:相似於session做用域,只是其用於portlet環境的web應用。若是在非portlet環境將視爲session做用域。

Bean的延遲加載

Bean默認是在容器初始化時就建立, 若是配置了延遲加載, 則會延遲Bean的實例化

<bean id="xxx" class="xxx" scope="singleton" lazy-init="true" />   <!-- 只有第一次獲取Bean纔會初始化Bean。若是Bean的scope是prototype,則每次獲取的時候都會初始化,無所謂延遲加載了 -->
<beans default-lazy-init="true">   <!-- 對全部Bean都應用延遲初始化 -->


Bean生命週期管理

第一步、構造函數初始化

第二步、調用set方法設置屬性

第三步、執行BeanNameAware的setBeanName()

第四步、執行BeanFactoryAware的setBeanFactory(),執行ApplicationContextAware的setApplicationContext

第五步、執行BeanPostProcessor的postProcessBeforeInitialization()

第六步、執行註解@PostConstruct方法

第七步、執行InitializingBean的afterPropertiesSet

第八步、調用init-method初始化方法

第九步、執行BeanPostProcessor的postProcessAfterInitialization


銷燬第一步、@PreDestroy 銷燬

銷燬第二步、執行DisposableBean接口的destroy方法

銷燬第三步、執行destroy-method


關於在spring  容器初始化 bean 和銷燬前所作的操做定義方式有三種:

第一種:經過@PostConstruct 和 @PreDestroy 方法 實現初始化和銷燬bean以前進行的操做

第二種是:經過 在xml中定義init-method 和  destory-method方法

第三種是: 經過bean實現InitializingBean和 DisposableBean接口

(後面會對生命週期從新開貼,補上代碼)

相關文章
相關標籤/搜索