Python 官方文档:入门教程 => 点击学习
目录一、Bean 的作用域二、spring 的执行流程三、Bean 的生命周期一、Bean 的作用域 在之前学习Java基础的时候,有接触到作用域这样的概念。一个变量并不一定在任何区
在之前学习Java基础的时候,有接触到作用域这样的概念。一个变量并不一定在任何区域都是有效的,限定这个变量的可用性的代码范围就是该变量的作用域。
但是在这里 Bean 的作用域的概念和以前所认为的作用域有所不同。
Bean 的作用域是指 Bean 在 Spring 整个框架中的某种行为模式。
接下来,将会举一个案例来讲讲什么是作用域,什么是行为模式
案例概要:
创建一个共有的 Bean ,使用者A和使用者B都对该 Bean 进行了使用
使用者A在进行使用的时候,创建一个新的变量接收注入进来的 Bean,进行修改,将修改后的结果进行返回;
使用者B 直接将注入进来的 Bean 进行返回,不进行任何操作
代码实现:
步骤一:创建出一个公共的 Bean
@Component
public class UserComponent {
@Bean
public User getUser() {
User user = new User();
user.setId(1);
user.setName("张三");
user.setPassWord("111111");
return user;
}
}
步骤二:使用者A获取到公共 Bean,进行修改
@Controller
public class UserControllerA {
@Autowired
private User user;
public User getUser1() {
System.out.println("使用者A拿到的原始user:" + user);
User myUser = user;
myUser.setName("李四");
return myUser;
}
}
步骤三:使用者B直接将获取到的公共的 Bean 进行返回
@Controller
public class UserControllerB {
@Autowired
private User user;
public User getUser2() {
return user;
}
}
步骤四:main 中获取 UserControllerA 类和 UserControllerB 类使用查看
public class Start {
public static void main(String[] args) {
//获取 Spring 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
//获取到Spring容器中的 UserControllerA 类(Bean 对象)
UserControllerA userControllerA = context.getBean("userControllerA",UserControllerA.class);
//使用 Bean 对象
System.out.println("使用者A->"+userControllerA.getUser1());
//获取到Spring容器中的 UserControllerA 类(Bean 对象)
UserControllerB userControllerB = context.getBean("userControllerB",UserControllerB.class);
//使用 Bean 对象
System.out.println("使用者B->"+userControllerB.getUser2());
}
}
预期结果:
使用者 A修改后,其结果是修改过的;使用者 B 没有修改过,其结果应该和原始user一样
结果显示:
和预期结果有所不同,使用者 A 和使用者 B 所得到的结果都是被修改过的。
这是因为在 Spring 中,Bean 默认情况下是单例状态,大家用的都是同一份对象,是全局共享的,当有其他人修改了该对象,另一个人所获取到的对象就是被修改过的,这便是 Bean 六大作用域之一——单例作用域(singleton)
在写 WEB 项目的时候,我们知道 DataSource 就是单例模式,使用单例,好处多多,可以确保所有对象都访问唯一实例,而且减少了内存的开支和系统性能的开销,因此 Bean 默认情况下是单例状态。
若想要按照预期结果输出,就需要将 Bean 的作用域设置成原型作用域,即无论谁来使用 Bean 对象,获取到的都是原始的 Bean 对象,大家各玩各的。
需要在注入的对象上使用注解修改作用域,有以下两种方法(Scope就是作用域的意思)
@Component
public class UserComponent {
//@Scope("prototype") //方法一
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) //方法二
@Bean
public User getUser() {
User user = new User();
user.setId(1);
user.setName("张三");
user.setPassWord("111111");
return user;
}
}
Bean 的 6 种作用域
singleton:单例作用域
prototype:原型作⽤域/多例作⽤域
request:请求作用域
session:会话作用域
application:全局作用域
websocket: HTTP WebSocket 作⽤域(不常用)
单例作用域和全局作用域比较像,但全局作用域范围没有单例作用域大,前者是 Spring 核心的作用域,后者是 Spring Web 中的作用域,前者作用于 IoC 容器,后者作用于 Servlet 容器
Spring 的执行流程也可以说是 Bean的执行流程,主要分成4部分
Bean 的生命周期即 Bean 从诞生到销毁的整个过程
实例化 Bean 对象,申请内存空间
设置 Bean 的属性,进行依赖注入和装配
Bean 的初始化
@PostConstructor
(对象加载完依赖注入后执行)init-method
使用 Bean
销毁 Bean
@PreDestroy
DisposableBean
destroy-method
补充
实例化和初始化的区别
@PostConstructor 和 @PreDestroy 是注解方式进行初始化和注销,init-method 和 destroy-method 是 XML 方法进行初始化和注销,一般只要使用其中的一种进行初始化
设置属性一定要在初始化之前,因为初始化也可能需要使用到注入的对象,如果没有进行属性的设置,初始化就会出现问题
案例:生命周期演示
@Component
public class BeanLife implements BeanNameAware {
@Override
public void setBeanName(String s) {
System.out.println("BeanName 感知:"+ s);
}
@PostConstruct
public void postConstructor() {
System.out.println("执行初始化方法:PostConstructor");
}
@PreDestroy
public void preDestroy() {
System.out.println("执行销毁方法:PreDestroy");
}
public void initMethod() {
System.out.println("执行初始化方法:init-method");
}
public void destroyMethod() {
System.out.println("执行销毁方法:destroy-method");
}
}
XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置一下:bean注解扫描的根路径(方面后面更简单存储对象到spring容器)-->
<content:component-scan base-package="com.bit.beans"></content:component-scan>
<beans>
<bean id="beanLife" class="com.bit.beans.Component.BeanLife" init-method="initMethod"
destroy-method="destroyMethod"></bean>
</beans>
</beans>
调用
public class Start {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("spring.xml");
BeanLife beanLife = context.getBean("beanLife",BeanLife.class);
System.out.println("---使用 Bean 对象---");
System.out.println("---注销 Bean 对象--- ");
context.destroy();//容器的销毁相当于销毁所有的 Bean
}
}
结果显示:
流程图展示:
到此这篇关于Java开发学习之Bean的作用域和生命周期详解的文章就介绍到这了,更多相关Bean作用域和生命周期内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: Java开发学习之Bean的作用域和生命周期详解
本文链接: https://www.lsjlt.com/news/151758.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0