Java|Java Spring中Bean的作用域及生命周期
目录
- 1.Bean的作用域
- 1.1 被修改的Bean案例
- 1.2 为什么使用单例模式作为默认作用域
- 1.3 作用域
- 1.4 Bean的6种作用域
- 1.5 设置作用域
- 2.Spring执行流程和Bean的生命周期
- 2.1 Bean的生命周期
- 2.1.1生命周期演示
- 2.1.2 为什么要先设置属性,在进行初始化
1.Bean的作用域
1.1 被修改的Bean案例
文章图片
原因:Bean的作用域默认是单例模式的,也就是说所有?的使?的都是同?个对象!之前我们学单例模式的时候都知道,使?单例可以很?程度上提?性能,所以在 Spring 中Bean 的作?域默认也是 singleton 单例模式。
@Componentpublic class Users {@Beanpublic User user1(){User user = new User(); user.setId(1); user.setName("Java"); return user; }}
@Componentpublic class Bean1 {@Autowiredprivate User user; public User getUser(){System.out.println("Bean1对象未修改name之前 : "+user); user.setName("C++"); return user; }}
@Componentpublic class Bean2 {@Autowiredprivate User user; public User getUser(){return user; }}
public class App {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); Bean1 bean1 = context.getBean("bean1",Bean1.class); System.out.println(bean1.getUser()); Bean2 bean2 = context.getBean("bean2",Bean2.class); System.out.println(bean2.getUser()); }}
1.2 为什么使用单例模式作为默认作用域
- 相同资源只创建一份,节省空间
- 不需要过多的创建和销毁对象,执行速度提高
1.3 作用域
作用域,一般理解为:限定程序中变量的可?范围叫做作?域,或者说在源代码中定义变量的某个区域就叫做作?域。
?
Bea
的作?域是指Bean
在 Spring
整个框架中的某种?为模式,?如singleton
单例作?域,就表示
Bean
在整个Spring
中只有?份,它是全局共享的,那么当其他?修改了这个值之后,那么另?个?读取到的就是被修改的值。
在Spring中,bean 的作用域被称为是行为模式,因为在Spring看来,单例模式,就是一种行为,意味着在整个Spring中bean只能存在一份。
1.4 Bean的6种作用域
- singleton:单例作?域
- prototype:原型作?域(多例作?域)
- request:请求作?域
- session:会话作?域
- application:全局作?域
- websocket:HTTP WebSocket 作?域
1.5 设置作用域
回到刚才的案例,Bean2希望获取到的bean对象是未被修改的,我们就可以将单例模式修改为多例模式。
使用@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
文章图片
文章图片
使用@Scope("prototype")
文章图片
2.Spring执行流程和Bean的生命周期
文章图片
ps
:当执行性到装配Bean的属性那一步时,当扫描到有属性注入时,会先停下类注入,优先进行属性注入,因为后面的方法可能会用到该属性。2.1 Bean的生命周期
所谓的生命周期指的是一个对象从诞生到销毁的整个生命过程,我们把这个过程就叫做一个对象的生命周期。
Bean 的生命周期分为以下5大部分:
- 1.实例化 Bean(为 Bean 分配内存空间)
- 2.设置属性(Bean 注入和装配)
- 3.Bean 初始化
实现了各种 Aware 通知的方法,如 BeanNameAware、BeanFactoryAware、 ApplicationContextAware 的接口方法,例如:Spring在初始化 bean,是需要给 bean 赋予 id(name)。而设置 beanName 成功的话,就会生成一个 beadNameAware 通知;执行 BeanPostProcessor 初始化前置方法(如果没有重写此方法,按照源码操作);执行 @PostConstruct 初始化方法,依赖注入操作之后被 执行;执行自己指定的 init-method 方法(如果有指定的话),是Spring中bean标签内指定的方法;
文章图片
这个初始化方法和上面一个用注解初始化的方法是两个不同时期的产物,init是xml时代产物,@PostConstruct是注解时代产物。优先级:当梁总方法同时存在时,优先执行注解,再执行init执行 BeanPostProcessor 初始化后置方法(如果没有重写此方法,按照源码操作)。
- 4.使用 Bean
- 5.销毁 Bean销毁容器的各种方法, 如 @PreDestroy、DisposableBean 接口方法、destroy-method。
优先级:@ProDestroy > 重写的DisposableBean接口方法 > destroy-method
执行流程图如下:
文章图片
ps:
实例化和初始化的区别:实例化
就是 分配内存空间。初始化
,就是把我们一些参数,方法的具体实现逻辑给加载进去。2.1.1生命周期演示
文章图片
文章图片
xml配置如下:
文章图片
Bean
public class BeanLifeComponent implements BeanNameAware {@PostConstructpublic void PostConstruct(){System.out.println("执行@PostConstruct"); }public void init(){System.out.println("执行bean-init-method"); }public void use(){System.out.println("正在使用bean"); }@PreDestroypublic void PreDestroy(){System.out.println("执行@PreDestroy"); }public void setBeanName(String s){System.out.println("执行了Aware通知"); }}
启动类
public class App2 {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); BeanLifeComponent beanLifeComponent = context.getBean(BeanLifeComponent.class); beanLifeComponent.use(); context.destroy(); }}
xml配置
2.1.2 为什么要先设置属性,在进行初始化
@Controllerpublic class TestUser {@Autowiredprivate Test test; public TestUser(){test.sayHi(); System.out.println("TestUser->调用构造方法"); }}
如果这段代码先执行了初始化,也就是其构造方法,会用到test对象,此时还没有设置属性,test就为null,会造成空指针异常。因此必须先设置属性,在进行初始化。
【Java|Java Spring中Bean的作用域及生命周期】到此这篇关于Java Spring中Bean的作用域及生命周期的文章就介绍到这了,更多相关Java Spring Bean 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- vue2.x中monaco-editor的使用说明
- java开发RocketMQ生产者高可用示例详解
- Monaco|Monaco Editor实现sql和java代码提示实现示例
- uniapp中用canvas实现小球碰撞的小动画
- 最新SpringCloud+SpringCloudAlibaba视频教程,Java自学/进阶程序员必看!
- Ant|Ant Design pro table表格选中后点击下一页上一页选中的内容丢失
- 艺视中国丨大胡子的英雄梦|艺视中国丨大胡子的英雄梦 车宝田
- 生产系统中的机器学习工程|基于 Docker 快速使用远程(云)数据库
- kubernetes|k8s中根据时间动态扩缩容
- 我敬佩的一个人