对于使用Spring框架的开发人员来说,做的两件事情就是:①开发Bean ②配置Bean
可以把Spring容器理解成一个工厂,Bean实例就是该工厂的产品,工厂(Spring容器)里能生产出来什么样的产品(Bean实例),取决于我们在配置文件中的配置。而Spring帮我们做的就是根据配置文件来创建Bean实例,并调用Bean实例的方法来完成“依赖注入”。
1. 容器中Bean的作用域
singleton | 使用 singleton 定义的Bean,只创建唯一实例 |
prototype | 每次获取Bean实例时,都创建一个新实例。(原型模式) |
request | 对于每次request,都创建一个新实例。 |
session | 对于每次session,都创建一个新实例。 |
global session | 每个全局的session,创建一个新实例。 |
1. 对于singleton,每次都获得唯一实例,Spring负责维护此实例的生命周期;(如果不指定,默认使用singleton)
2. 对于prototype,每次获取Bean实例,都创建一个新实例,Spring不再维护实例的生命周期。创建销毁实例代价比较大。
3. 使用 request,session,global session,在配置Bean之前,需要做少量的初始配置。(将http请求绑定到提供该服务的线程上,这使得具有request 和 session的Bean实例能够被访问到)
4. 如果使用SpringMVC,则无须设置,因为DispatcherServlet 和DispatcherPorlet已经执行了相应的处理。
使用DispatcherServlet 以外的Servlet, 2.4及以上规范的Web 容器需要在“web.xml”中如下配置:
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
早期版本的Web容器,不支持Listener ,只能改为Filter配置方式:
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2. 容器中Bean的生命周期
Spring可以管理singleton的Bean的生命周期,Spring可以知道bean何时被创建,何时初始化,何时销毁Bean实例。
Bean初始化两种方式:
1. 使用init-method 属性(松耦合)
在类中编写一个方法,在属性中指定该方法在依赖关系设置完成后自动执行。
2. 实现InitializingBean接口,实现afterPropertiesSet()方法(紧耦合)
Bean销毁两种方式:
1. 使用 destroy-method属性
2. 实现DisposableBean接口,实现destroy()方法。
prototype的Bean,Spring容器只负责Bean的创建。每次请求prototype的Bean时,都会产生一个新的Bean实例。
3. Spring 的 Bean 和 JavaBean比较
-
- Spring 中的Bean 是放在容器中的任意一个类的对象;而JavaBean是具有无参构造方法的实体类。
4. Spring 的Bean继承
-
- Spring中子Bean和父Bean可以是不同的类型。
- Spring中Bean的继承是实例之间的关系,主要表现为参数值的延续。
5. Bean 实例的创建方式及依赖配置
大多数情况下,BeanFactory 直接通过new创建Bean 实例,而class属性指定了Bean实例的实现类。但这并不是实例化Bean的唯一方法。
6. 创建Bean三种方式
1) 调用构造方法
BeanFactory 将使用默认的构造方法来创建Bean实例,对此实例的所有属性执行默认初始化,即所有基本类型的值初始化为0或false,引用类型初始化为null,接下来BeanFactory会根据配置文件,创建依赖的其他Bean 实例,然后为Bean注入依赖的其他实例。
2) 使用静态工厂方法
使用静态工厂方法创建Bean实例时,class属性指定的是静态工厂类,根据工厂类的工厂方法来创建Bean实例;此外,还需要使用factory-method 属性来指定静态工厂方法名。
使用静态工厂方法创建Bean实例时,Spring将先解析配置文件,通过反射调用静态工厂类的静态工厂方法。
3) 使用实例工厂方法
调用实例工厂方法则必须使用工厂实例。使用实例工厂方法时,配置的<bean../>无需class属性,需要如下两个属性:factory-bean属性,factory-method属性。如果需要调用工厂方法时传入参数,使用<constructor-arg.../>。
静态工厂方法和实例工厂方法的不同点:
1. 调用实例工厂方法创建Bean,必须使用factory-bean属性确定工厂Bean。而静态工厂方法创建Bean,则使用class 元素确定静态工厂类。
静态工厂方法和实例工厂方法的相同点:
1. 都需要factory-method 指定工厂方法。
2. 都可以使用<constructor-art.../>元素指定参数。