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接口
(后面会对生命周期从新开贴,补上代码)