深入Bean对象
- 1. Bean对象的作用域
- 1.1 引出作用域问题
- 1.2 六种作用域
- 2. Spring的执行流程
- 3. Bean对象的生命周期
在之前的学习中,我们了解到Spring能够用来帮助我们管理Java中的Bean对象,我们能够向Spring的IOC容器中添加以及获取对象。那我们从Spring对象中获取到的相同Bean对象始终是同一个吗?Spring是怎样对我们的Bean对象进行管理的呢?Spring又是怎么执行的呢?接下来我们一块儿来探索一番!
1. Bean对象的作用域
1.1 引出作用域问题
通常情况下,我们使用公共Bean对象都是希望这个公共的Bean对象是在被用户获取后在自己的工作区域中被修改,而不影响其他用户的工作区域。而Spring默认情况下Bean的作用域是被所有用户所共享的,这可能就会带来一些问题。我们通过下面这个栗子来引出有关Bean对象的作用域问题:
我们假设现在有一个公共的Bean对象,多个用户都可以来操作这个Bean对象,其中有一个用户对公共的Bean对象进行了修改,我们来看看其他用户获取到的公共的Bean对象会发生什么?
1.2 六种作用域
Spring容器在初始化一个Bean的同时会指定这个Bean的作用域。Bean对象的作用域共有以下六种:
- singleton——单例作用域
- prototype——原型作用域(即多例作用域)
- request——请求作用域
- session——会话作用域
- application——全局作用域
- websocket——HTTP websocket作用域
我们来详细了解一下这些个作用域具体说明:
- singleton——单例作用域 该作用域下的Bean对象在IOC容器中只存在一份,任何的获取方式获取到的Bean对象都是同一份,并且不同工作对Bean的修改对其他工作可见。因此这种作用域适用于无状态的Bean使用,所谓无状态的Bean值得就是不需要修改的只读的对象。Spring默认选择的就是这种作用域。这种作用域就是我们在1.1
引出作用域问题中举的例子。- prototype——原型作用域 针对该作用域下的Bean请求,每次都会返回一个新的Bean对象。通过Spring上下文对象的getBean获取或者注解Autowired/Resource注入的Bean对象都是ioc容器中对应Bean的又一份新的实例!因此这种作用域适合于有状态的Bean对象使用。例如,我们需要实现1.1
引出作用域问题例子的预期效果,可以针对User对象设置其作用域为prototype,这样userController对Bean对象的修改也只是针对自己的bean对象进行了修改,对UserEnhanceController也就不可见了,如下:
- request、session、application、websocket都是在SpringMVC中使用的,我们学到后边再进行详细的总结。下面先简单总结下:
- request作用域:每次的HTTP请求都会创建新的Bean实例,获取或者装配的Bean对象也都是新的。
- session作用域:使用这个作用域的Bean对象可以被同个用户共享,比如可以用来存放用户登录的信息。
- application全局作用域:这个作用域下的Bean对象被WEB应用的上下文信息共享。通常记录一个应用的共享信息。
到这里,我们会发现:singleton单例作用域和application作用域好像啊,但是他们是完全不相同的。那么应该怎么区分二者呢?
①首先,针对对象不同。singleton针对的是spring-core项目;application针对的是SpringWeb项目。
②其次,作用对象不同:singleton作用域IOC容器,而application作用与web servlet容器。
2. Spring的执行流程
了解了Bean对象的作用域,我们得先弄明白Spring到底是怎么执行的,才能够清楚我们Bean对象生命周期的根源,我们一起来看下Spring的执行流程:
3. Bean对象的生命周期
在学习Bean对象的生命周期之前,我们必须先清楚什么是生命周期?生命周期指的就是一个事物从新生到灭亡的整个过程。在这里指的就是Bean对象从被创建到被销毁的整个过程。Bean对象的生命周期可以分为以下5部分,我们挨个来看:
在这个过程中,Bean的初始化是一个相对复杂的过程。
1. 实现了各种通知方法,像BeanNameAware、BeanFacctoryAware、ApplicationContext的接口方法。
2. 执行BeanPostProcessor初始化前置方法。
3. 执行@PostConstruct初始化方法,该方法在依赖注入操作之后执行。
4. 执行init-method方法
5. 执行BeanPostProcessor初始化后置方法。
我们也可以类比人的一生来理解Bean对象的一生…,Bean对象的一生,像极了人的一生:
Bean对象完整的生命周期图解如下: