spring bean
(参考内容)
Bean的作用域###
Singleton 单例 在Spring IOC 容器仅存在一个Bean实例,Bean以单例方式存在,这个是默认值。
prototype 原型 每次从容器调用bean时,都会返回一个新的实例,也就是每次调用getBean()时都会实例化一个新的bean。
request 每次HTTP请求都会创建一个新的Bean,该作用于仅适用于web环境
session 每个HTTP Session共享一个Bean,不同的Session使用不同的Bean,同样只适用于web环境。
Global Session 一般作用于Portlet应用环境,只作用于Web环境。
五种作用域中,其中request、session、global session三种作用域仅适用于web环境
Bean初始化###
bean对象无外乎是在以下两个时刻进行实例化的:
调用getBean()方法时。
Spring容器启动时。
-
bean的作用域为singleton时,bean对象是在Spring容器启动时就进行创建。
但我们也可以指定bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。
如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true”,如下:<?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" default-lazy-init="true"> ...... </beans>
-
bean的作用域为prototype时,bean对象并不会在Spring容器启动时就进行创建,bean对象将会在调用getBean()方法时进行创建。
初始化方法和销毁方法###
<?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="personService" class="cn.itcast.service.impl.PersonServiceBean" lazy-init="false"
init-method="init" destroy-method="destroy" />
</beans>
将会在bean初始化和销毁的时候,执行bean内的方法。
试着思考这样一个问题:bean对象到底是什么时候销毁的呢?答案是:如果没有人为地删除它,默认该bean一直在Spring容器中,也就是说随着Spring容器的关闭,该bean才会被销毁。
Autowire Resource 比较###
@Autowired默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配
@Autowired + @Qualifier("...") = @Resource(name="...")
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如:
@Autowired(required=true) @Qualifier("personDaoxxxx") private PersonDao personDao;
required=true代表字段personDao必须要注入值,也即是说在Spring容器中根据类型找不到对应的bean,那就会报异常;
required=false意味着在Spring容器中根据类型找不到对应的的bean,就会把该字段设为null。
-
依赖注入——自动装配依赖对象
<bean id="..." class="..." autowire="byType"/>
autowire属性取值如下:
- byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。
- byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到,即属性值为null。
- constructor与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
- autodetect:通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。
@Resource默认按名称装配
@Resource(name="personDaoBean")
private PersonDao personDao; // 用于字段上
@Resource
public void setPersonDao(PersonDao personDao) { // 用于属性的setter方法上
this.personDao = personDao;
}
注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
举例如下:
@Resource
private PersonDao personDao;
<bean id="personDao" class="cn.itcast.dao.impl.PersonDaoBean"></bean> 可以
<bean id="personDaoxxxx" class="cn.itcast.dao.impl.PersonDaoBean"></bean> 可以
@Resource(name="personDaoxxxx")
private PersonDao personDao;
<bean id="personDao" class="cn.itcast.dao.impl.PersonDaoBean"></bean> 不可以
<bean id="personDaoxxxx" class="cn.itcast.dao.impl.PersonDaoBean"></bean> 可以