Spring Bean的作用域和生命周期

354 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情

Spring Bean的作用域和生命周期 一、Bean的作用域 在Bean容器启动会读取bean的xml配置文件,然后将xml中每个bean元素分别转换成BeanDefinition对象。在BeanDefinition对象中有scope 属性,就是它控制着bean的作用域。 Spring框架支持5种作用域,有三种作用域是当开发者使用基于web的ApplicationContext的时候才生效的。下面就是Spring直接支持的作用域了,当然开发者也可以自己定制作用域。

作用域描述:

单例(singleton)(默认)每一个Spring IoC容器都拥有唯一的一个实例对象。

原型(prototype)一个Bean定义,任意多个对象请求(request)一个HTTP请求会产生一个Bean对象,也就是说,每一个HTTP请求都有自己的Bean实例。只在基于web的Spring ApplicationContext中可用 会话(session) 限定一个Bean的作用域为HTTPsession的生命周期。同样,只有基于web的Spring ApplicationContext才能使用。

全局会话(global session) 限定一个Bean的作用域为全局HTTPSession的生命周期。通常用于门户网站场景,同样,只有基于web的Spring ApplicationContext可用。

二、Bean的生命周期

前面章节介绍了bean容器以及bean的配置与注入,本章学习bean的生命周期,了解bean是怎么来的又是怎么没的。

ApplicationContext容器中,Bean的生命周期流程如上图所示,流程大致如下:

首先容器启动后,会对scope为singleton且非懒加载的bean进行实例化, 按照Bean定义信息配置信息,注入所有的属性, 如果Bean实现了BeanNameAware接口,会回调该接口的setBeanName()方法,传入该Bean的id,此时该Bean就获得了自己在配置文件中的id,如果Bean实现了BeanFactoryAware接口,会回调该接口的setBeanFactory()方法,传入该Bean的BeanFactory,这样该Bean就获得了自己所在的BeanFactory, 如果Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()方法,传入该Bean的ApplicationContext,这样该Bean就获得了自己所在的ApplicationContext, 如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()方法, 如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法, 如果Bean配置了init-method方法,则会执行init-method配置的方法, 如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法, 经过流程9之后,就可以正式使用该Bean了,对于scope为singleton的Bean,Spring的ioc容器中会缓存一份该bean的实例,而对于scope为prototype的Bean,每次被调用都会new一个新的对象,期生命周期就交给调用方管理了,不再是Spring容器进行管理了 容器关闭后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法, 如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean的生命周期结束。 这里在UserBean类基础上进行改造,增加了name属性并实现了ApplicationContextAware接口。

注解 @PathVariable :

通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。

@RequestBody和@RequestParam

两个注解都是用于方法中接收参数使用的,两者也有一定的区别。 @RequestBody这个一般处理的是在ajax请求中声明contentType: “application/json; charset=utf-8”时候。也就是json数据或者xml(我没用过这个,用的是json) @RequestParam这个一般就是在ajax里面没有声明contentType的时候,为默认的urlencode格式时,用这个。 @RequestBody可以直接将页面中的参数封装成实体类中的数据传输给后端 @PostMapping @GetMapping @RequestMapping

@GetMapping是一个组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写。

@PostMapping是一个组合注解,是@RequestMapping(method = RequestMethod.POST)的缩写。

@RequestMapping是一个非 组合注解,需要自定义请求方式。

@RestController和@Controller

RestController相当于Controller+ResponseBody注解。如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html,配置的视图解析器 ,也就是相当于在方法上面自动加了ResponseBody注解,所以没办法跳转并传输数据到另一个页面,所以InternalResourceViewResolver也不起作用,返回的内容就是Return 里的内容,即数据直接甩在当前请求的页面上,适用于ajax异步请求。