区块链交易网站建设,免费空间说说点赞,wordpress 引用菜单,高端网站建设一般多少钱Bean作用域和生命周期 一. Bean 的作用域1. Bean 的 6 种作⽤域#xff1a;①. singleton②. prototype③. request④. session⑤. application⑥. websocket单例作用域(singleton) VS 全局作⽤域(application) 2. 设置作用域 二. Spring 执行流程和 Bean 的生命周期1. Spring… Bean作用域和生命周期 一. Bean 的作用域1. Bean 的 6 种作⽤域①. singleton②. prototype③. request④. session⑤. application⑥. websocket单例作用域(singleton) VS 全局作⽤域(application) 2. 设置作用域 二. Spring 执行流程和 Bean 的生命周期1. Spring 执行流程2. Bean 生命周期 假设现在有⼀个公共的 Bean提供给 A ⽤户和 B ⽤户使⽤然⽽在使⽤的途中 A ⽤户却“悄悄”地修改了公共 Bean 的数据导致 B ⽤户在使⽤时发⽣了预期之外的逻辑错误。
我们预期的结果是公共 Bean 可以在各⾃的类中被修改但不能影响到其他类。
公共 Bean
Component
public class Users {Beanpublic User user1() {User user new User();user.setId(1);user.setName(Java); // 【重点名称是 Java】return user;}
}A ⽤户使⽤时进⾏了修改操作
Controller
public class UserController {Autowiredprivate User user1;public User getUser1() {User user user1;System.out.println(Bean 原 Name user.getName());user.setName(悟空); // 【重点进⾏了修改操作】return user;}
}B ⽤户再去使⽤公共 Bean
Controller
public class UserController2 {Autowiredprivate User user1;public User getUser1() {User user user1;return user;}
}
打印 A ⽤户和 B ⽤户公共 Bean 的值
public class App {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);UserController userController context.getBean(UserController.class);System.out.println(A 对象修改之后 Name userController.getUser1().toString());UserController2 userController2 context.getBean(UserController2.class);System.out.println(B 对象读取到的 Name userController2.getUser1().toString());}
}A 修改过 Bean 之后B 再去使用是是修改过的值。
原因
Bean 默认情况下是单例状态singleton也就是所有⼈的使⽤的都是同⼀个对象使⽤单例可以很⼤程度上提⾼性能所以在 Spring 中Bean 的作⽤域默认也是 singleton 单例模式。
一. Bean 的作用域
限定程序中变量的可⽤范围叫做作⽤域或者说在源代码中定义变量的某个区域就叫做作⽤域。
⽽ Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式 ⽐如 singleton 单例作⽤域就表示 Bean 在整个 Spring 中只有⼀份它是全局共享的那么当其他⼈修改了这个值之后那么另⼀个⼈读取到的就是被修改的值。
1. Bean 的 6 种作⽤域
singleton单例作⽤域prototype原型作⽤域多例作⽤域request请求作⽤域session会话作⽤域application全局作⽤域websocketHTTP WebSocket 作⽤域
注意后 4 种状态是 Spring MVC 中的值在普通的 Spring 项⽬中只有前两种。
①. singleton
描述该作⽤域下的Bean在IoC容器中只存在⼀个实例获取Bean即通过 applicationContext.getBean 等⽅法获取及装配Bean即通过Autowired注⼊都是同⼀个对象。场景通常⽆状态的Bean使⽤该作⽤域。⽆状态表示Bean对象的属性状态不需要更新备注Spring默认选择该作⽤域
②. prototype
描述每次对该作⽤域下的Bean的请求都会创建新的实例获取Bean即通过applicationContext.getBean等⽅法获取及装配Bean即通过Autowired注⼊都是新的对象实例。场景通常有状态的Bean使⽤该作⽤域
③. request
描述每次 http 请求会创建新的 Bean 实例类似于 prototype场景⼀次 http 的请求和响应的共享 Bean备注限定 SpringMVC 中使⽤
④. session
描述在⼀个 http session 中定义⼀个 Bean 实例场景⽤户会话的共享 Bean, ⽐如记录⼀个⽤户的登陆信息备注限定 SpringMVC 中使⽤
⑤. application
描述application作用域的Bean将在应用程序启动时创建并在应用程序关闭时销毁。场景通常用于需要在整个应用程序中共享数据或资源的情况它可以确保在应用程序的不同部分之间共享相同的Bean实例。备注限定SpringMVC中使用
⑥. websocket
描述在⼀个 HTTP WebSocket 的⽣命周期中定义⼀个 Bean 实例场景WebSocket 的每次会话中保存了⼀个 Map 结构的头信息将⽤来包裹客户端消息头。第⼀次初始化后直到 WebSocket 结束都是同⼀个 Bean 。备注限定 Spring WebSocket 中使⽤
单例作用域(singleton) VS 全局作⽤域(application)
singleton 是 Spring Core 的作⽤域application 是 Spring Web 中的作⽤域singleton 作⽤于 IoC 的容器⽽ application 作⽤于 Servlet 容器。
2. 设置作用域
使⽤ Scope 标签就可以⽤来声明 Bean 的作⽤域⽐如设置 Bean 的作⽤域
Component
public class Users {Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)Bean(name u1)public User user1() {User user new User();user.setId(1);user.setName(Java); // 【重点名称是 Java】return user;}
}Scope 标签既可以修饰⽅法也可以修饰类Scope 有两种设置⽅式
直接设置值Scope(“prototype”)使⽤枚举设置Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
二. Spring 执行流程和 Bean 的生命周期
1. Spring 执行流程 Bean 执⾏流程Spring 执⾏流程启动 Spring 容器 - 加载配置文件扫描对应包下面的注解 - (将 Bean 存入到 IoC 容器中) 实例化、设置属性、初始化 - 将 Bean 装配到需要的类中取操作)。
2. Bean 生命周期
⽣命周期指的是⼀个对象从诞⽣到销毁的整个⽣命过程我们把这个过程就叫做⼀个对象的⽣命周期。
Bean 的⽣命周期分为以下 5 ⼤部分
实例化 Bean为 Bean 分配内存空间设置属性Bean 注⼊和装配注入自己依赖的类Bean 初始化 实现了各种 Aware 通知的⽅法如 BeanNameAware、BeanFactoryAware、ApplicationContextAware 的接⼝⽅法 执行 BeanPostProcessor 初始化前置⽅法 执行 PostConstruct 初始化⽅法依赖注⼊操作之后被执⾏ 执行自己指定的 init-method ⽅法如果有指定的话 执行 BeanPostProcessor 初始化后置⽅法。使用 Bean销毁 Bean 销毁容器的各种⽅法如 PreDestroy、DisposableBean 接⼝⽅法、destroy-method。
执⾏流程如下图所示 举个栗子 ⽐如我们现在需要买⼀栋房⼦那么我们的流程是这样的
先买房实例化从⽆到有装修设置属性买家电如洗⾐机、冰箱、电视、空调等[各种]初始化⼊住使⽤ Bean卖出去Bean 销毁。
实例化和初始化的区别
实例化和属性设置是 Java 级别的系统“事件”其操作过程不可⼈⼯⼲预和修改⽽初始化是给开发者 提供的可以在实例化之后类加载完成之前进⾏⾃定义“事件”处理。
为什么要先设置属性在进行初始化呢
因为初始化时可能需要用到注入进来的类确保Bean在初始化时具备正确的依赖关系和一致的状态以避免潜在的问题。 所以说假如 A 依赖 B 当进行设置属性时发现容器中没有 B那么就会先将 B存入到容器中再将 B 注入到 A 中。
好啦 以上就是对 Spring Bean作用域和生命周期的讲解希望能帮到你 评论区欢迎指正 !