JavaEE Bean的两种常用作用域singleton(单例)和prototype(原型)。
作用域名称 | 说明 |
---|---|
singleton | 使用singleton定义的Bean在spring容器中将只有一个实例,也就是说无论有多少个Bean在引用他,始终指向一个对象,这也是spring容器默认的作用域 |
prototype(原型) | 每次通过spring容器获取的prototype定义的Bean时,容器将创建一个新的Bean对象 |
- singleton作用域
创建一个类:
public class LoginResource {
}
创建一个配置文件:作用域定义为singleton
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="loginResource" name="loginResource" class="com.dalingjia.spring.service.LoginResource" scope="singleton"> </bean>
</beans>
测试类:
package com.dalingjia.spring;
import com.dalingjia.spring.service.LoginResource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestClient {
/**
* 1, 解析applicationgContext.xml,将xml中定义的bean(如loginService和loginResource)解析成Spring内部的BeanDefinition,
* 并以beanName(如loginService)为key,BeanDefinition(如loginService相应的BeanDefinition)为value存储到DefaultListableBeanFactory中的beanDefinitionMap(其实就是一个ConcurrentHashMap)中,
* 2, 同时将beanName存入beanDefinitionNames(List类型)中,然后遍历beanDefinitionNames中的beanName,进行bean的实例化并填充属性,
* 在实例化的过程中,如果有依赖没有被实例化将先实例化其依赖,然后实例化本身,实例化完成后将实例存入单例bean的缓存中,
* 当调用getBean方法时,到单例bean的缓存中查找,如果找到并经过转换后返回这个实例(如LoginResource的实例),之后就可以直接使用了
*/
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
LoginResource loginResource1 = (LoginResource) applicationContext.getBean("loginResource");
LoginResource loginResource2 = (LoginResource) applicationContext.getBean("loginResource");
System.out.println(loginResource1);
System.out.println(loginResource2);
}
}
输出结果:
com.dalingjia.spring.service.LoginResource@508dec2b
com.dalingjia.spring.service.LoginResource@508dec2b
一共发起了2次Bean请求,但是2次Bean实例对象都相同,这说明被定义作用域为singleton的Bean如果请求ID相同则会返回相同的Bean实例。
- prototype作用域
将上面作用域设置为prototype,再次运行,输出结果如下:
com.dalingjia.spring.service.LoginResource@3bd40a57
com.dalingjia.spring.service.LoginResource@fdefd3f
总结:
- 默认情况下的spring bean都为单例bean,即context创建的时候就已经创建,我们可以通过设置bean的scope属性为prototype来设置bean为原型bean,使得实例在使用的时候才去创建,而且每次创建都是不同的实例。
- spring中bean默认是sinleton的,延迟加载为false 。即如果想要一个类延迟实例化,那么将其的lazy-init=”true”或改变其 scope(类的管理方式)。
SpringMVC核心处理流程:
1、DispatcherServlet前端控制器接收发过来的请求,交给HandlerMapping处理器映射器
2、HandlerMapping处理器映射器,根据请求路径找到相应的HandlerAdapter处理器适配器(处理器适配器就是那些拦截器或Controller)
3、HandlerAdapter处理器适配器,处理一些功能请求,返回一个ModelAndView对象(包括模型数据、逻辑视图名)
4、ViewResolver视图解析器,先根据ModelAndView中设置的View解析具体视图
5、然后再将Model模型中的数据渲染到View上
这些过程都是以DispatcherServlet为中轴线进行的。