Spring對Bean的管理包括Bean的初始化、Bean的注入、Bean的生命週期管理、Bean的做用域管理....等。Spring提供了三種實例化Bean的方式:使用類構造器、使用靜態工廠類、使用工廠類;Spring經過依賴注入(DI)解耦對象的依賴關係,並提供了構造注入、設值注入兩種注入方式;Spring提供「singleton」和「prototype」兩種基本做用域,另外提供「request」、「session」、「global session」三種web做用域,Spring還容許用戶定製本身的做用域。java
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(); } }
依賴注入的原理很簡單,即利用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(); } }
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 id="xxx" class="xxx" scope="singleton" lazy-init="true" /> <!-- 只有第一次獲取Bean纔會初始化Bean。若是Bean的scope是prototype,則每次獲取的時候都會初始化,無所謂延遲加載了 --> <beans default-lazy-init="true"> <!-- 對全部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接口
(後面會對生命週期從新開貼,補上代碼)