【JavaEE】Bean的作用域和生命周期

news2024/9/19 10:36:17

目录

Bean的作用域

作用域分类

设置作用域

通过注解设置

通过配置文件设置

Bean的生命周期


Bean的作用域

Bean的作用域是指:在整个Spring容器中Bean的行为模式。这个模式有六种。

作用域分类

  1. singleton:单例作用域

    在这个模式下,容器一启动就会创建出一个实例化的Bean对象,后续使用它时,都是直接对它进行操作,直到最后容器销毁Bean才会销毁。

    适用于Bean状态不需要更新的情况。
  2. prototype:原型作用域(多例作用域)。

    在这个模式下,只要请求Bean,Spring都会创建出一个新的实例返回,当实例使用完成后就会自动销毁。

    适用于Bean状态需要更新的情况。

    以下三种只适用于Spring MVC
  3. request:请求作用域。

    每个HTTP请求(request)中只有一个实例化的Bean对象。同一个请求中的所有处理都共享该Bean实例。该作用域下的Bean会在每个请求(request)中被创建,当请求结束时被销毁。
  4. session:会话作用域。

    每个HTTP会话(session)中只有一个实例化的Bean对象。同一个会话中所有的请求都共享该Bean实例。该作用域下的Bean会在每个会话(session)中被创建,当会话结束时被销毁。
  5. application:全局作用域。

    所有Web应用中只有一个实例化的Bean对象,同一个Web应用中的所有请求都共享该Bean实例。该作用域下的Bean会在Web应用启动时被创建,当Web应用关闭时被销毁。

    和singleton的区别
    1. singleton是Spring Core的作用域,application是Spring MVC的
    2. singleton是作用于IoC容器,application是作用于Servlet容器
  6. websocket:HTTP WebSocket作用域。

    在一个HTTP WebSocket的生命周期中,定义一个实例。
    只能在HTTP WebSocket中使用。

由于我们目前的项目是Spring Core项目,目前只可以演示单例作用域和原型作用域。现在来演示一下单例作用域的效果。

package com.test.entity;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@ToString
public class User {
    private Integer id;
    private String name;
}
package com.test.repository;

import com.test.entity.User;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;

@Repository
public class BuildUser {
    @Bean
    public User user() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        return user;
    }
}

这里使用方法注解把User存到了Spring容器中。 接下来使用Controller从Spring获取到User,然后修改名字。最后Service从Spring中获取到User,查看是否和最开始的User一样。

package com.test.controller;

import com.test.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    @Autowired
    private User user;

    public User getUser() {
        User user1 = user;
        user1.setName("李四");
        return user1;
    }
}
package com.test.service;

import com.test.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    private User user;

    public User getUser() {
        User user1 = user;
        return user1;
    }
}

最后打印一下User,看看是否符合单例的模式。

import com.test.controller.UserController;
import com.test.entity.User;
import com.test.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

        User user1 = context.getBean("user", User.class);
        System.out.println("直接拿最开始存的User:" + user1.toString());

        UserController userController = context.getBean("userController", UserController.class);
        System.out.println("在UserController修改后返回的User:" + userController.getUser().toString());

        UserService userService = context.getBean("userService", UserService.class);
        System.out.println("在UserService中得到开始的User:" + userService.getUser().toString());
    }
}


设置作用域

默认的作用域是单例作用域,当我们想要更改其作用域是,通过注解和配置文件的方式更改。建议使用注解的方式

通过注解设置

@Scope  使用这个注解来改变当前bean的作用域。

需要设置在其他注解的上面,因为一开始就要确认其存储方法

有两种方法可以设置,推荐第一种

  1. @Scope("在这里设置作用域")  比如 @Scope("ConfigurableBeanFactory.SCOPE_PROTOTYPE")  这个类中的常量是给我们设置好了,这样可以防止拼错
  2. @Scope("在这里设置作用域")  比如
    @Scope("prototype")  这样需要自己拼写,容易拼错。

把上述的Bean从单例作用域变成原型作用域。

package com.test.repository;

import com.test.entity.User;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;

@Repository
public class BuildUser {
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Bean
    public User user() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        return user;
    }
}

通过配置文件设置

这里需要到配置文件中修改 bean 属性scope

    <bean id="buildBean" class="com.test.repository.BuildUser" scope="prototype"></bean>

效果同上。

如果二者同时设置了,并且有冲突,注解的方法优先级高于配置文件。 


Bean的生命周期

Bean的生命周期主要有五大部分。

  1. 实例化Bean:为Bean分配空间
  2. 设置属性:在Bean的注入和装配时需要设置属性
  3. Bean初始化
    1. 实现各种Aware通知方法
      BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法
    2. 执行BeanPostProcessor初始化前置方法
    3. 执行PostConstruct初始化方法,在依赖注入后实现
    4. 执行用户自己指定的init-method(如果有)
    5. 执行BeanPostProcessor初始化后置⽅法
  4. 使用Bean
  5. 销毁Bean
    销毁容器的各种⽅法,如 PreDestroy、DisposableBean 接⼝⽅法、destroy-method
package com.test.controller;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Controller;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Controller
public class BeanLifeController implements BeanNameAware, BeanPostProcessor {
    @Override
    public void setBeanName(String s) {
        System.out.println("执行了通知Bean" + s);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行了postProcessAfterInitialization方法");
        return bean;
    }

    public void myInit() {
        System.out.println("执行了XML的初始化方法");
    }

    @PostConstruct
    public void doConstruct() {
        System.out.println("执行了使用注解的初始化方法");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行了postProcessBeforeInitialization方法");
        return bean;
    }

    public void sayHi() {
        System.out.println("你好");
    }

    @PreDestroy
    public void doPreDestroy() {
        System.out.println("执行了销毁Bean容器的方法");
    }

}

还有一些存Bean的代码不作展示了。

import com.test.controller.BeanLifeController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        BeanLifeController beanLifeController = context.getBean("beanLifeController", BeanLifeController.class);
        beanLifeController.sayHi();
        beanLifeController.doPreDestroy();
    }
}

其中初始化使用了两种方式实现:


有什么错误评论区指出,希望可以帮到你。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/448515.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络地址转换应用

如图所示,企业使用一台AR 路由器作为出口设备,路由器配置NAT Outbound为私网用户提供访问Internet服务,同时配置NAT Server将私网WEB服务器发布到公网上,对外网用户提供服务。运营商仅为该单位分配了一个公网IP,此地址既作为AR出接口的IP地址,也作为NAT Outbound和NAT Se…

【Atlas500】华为Atals MindStudio配置指南

目录 安装推理用ubuntu版docker配置docker内的ssh服务安装ubuntu系统中的依赖项&#xff1a;检查root用户的umask安装依赖项安装CANN连接到CANN Setting 安装推理用ubuntu版docker 华为的atlas500自带的欧拉系统是一个裁剪系统&#xff0c;一般通过在其上运行官方的ubuntu dock…

【消息队列】Kafka高水位和Leader Epoch原理

什么是高水位 首先高水位也就是HW&#xff0c;而对应的有LEO&#xff0c;其实这都是Kafka副本中针对位移的概念&#xff0c;其目的就是为了保证多副本间数据的一致性。 LEO &#xff08;Log End Offet&#xff09;&#xff1a;每个副本的最后一个offset&#xff0c;LEO其实就是…

你猜我猜不猜 (猜数字游戏) 快来小玩一把叭

&#x1f929;本文作者&#xff1a;大家好&#xff0c;我是paperjie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 &#x1f970;内容专栏&#xff1a;这里是《C语言》专栏&#xff0c;笔者用重金(时间和精力)打造&#xff0c;将C语言知识一网打尽&#xff0c;希望可…

解决Vue热更新失效问题

解决Vue热更新失效 一、问题描述二、出现原因三、解决方案四、总结 &#x1f680; 欢迎访问我的个人博客&#xff1a;https://wk-blog.vip 一、问题描述 之前在本地测试Vue项目时&#xff0c;是可以热更新的&#xff0c;但是最近一段时间发现Vue的热更新失效了。然后通过vs co…

【大厂直通车】美团_测开面经

哈喽,大家好,我是小浪;那么最近暑假实习,日常实习是卷的飞起,无论是开发岗,测试岗,算法岗,都一片死寂;不过还是有很多大佬,成功绞杀很多大厂,offer也是拿到手软; 团子暑期实习offer: 📱本专栏致力于持续更新最新各大厂面经,实习消息,招聘要求; 那么目前价格…

ISCSI个人理解与简要说明

ISCSI个人理解与简要说明 一、如何理解ISCSI二、iscsi 命令iscsiadm&#xff08;管理客户端&#xff09;tgtadm&#xff08;管理服务端&#xff09; 三、ISCSI中的概念四、从DAS&#xff0c;NAS&#xff0c;SAN的角度扩展理解ISCSI 一、如何理解ISCSI 理解一个东西&#xff0c…

Niginx的rewrite

常用的Nginx正则表达式 ^匹配输入字符串的起始位置 $匹配输入字符串的结束位置 *匹配前面的字符零次或多次。如“ol*" 能匹配"o”及“ol”、“oll” 匹配前面的字符一次或多次。如“ol" 能匹配“ol"及“ol1”、“olll"&#xff0c; 但不能匹配“o” ?…

服务器版本的表白墙

目录 1.步骤 2.提供两个接口: 3.流程 4.代码 1.前端代码 2.sql创建表 3.后端代码 MessageServlet.java DBUtil.java 1.步骤 1.约定前后端交互的接口 2.开发服务器代码 a.编写servlet处理前端发来的请求 b.编写数据库代码,存储获取关键的数据 3.开发客户端代码 a.基于…

java学习中遇到的问题及解答

你好&#xff0c;我想问一下&#xff0c;为什么在idea编译环境下&#xff0c;有异常的地方它会报错&#xff0c;让你主动添加抛出错误代码呢&#xff1f; 在Java中&#xff0c;有两种类型的异常&#xff0c;一种是受检异常&#xff08;checked exception&#xff09;&#xff0…

一级结构规范 合集

极限状态设计原则4.1限态4.11 极限状态可分为承载能力极限状态、正常使用极限状态和耐久性极限状态。极限状态应符合下列规定:1当结构或结构构件出现下列状态之一时&#xff0c;应认定为超过了承载能力极限状态;1) 结构构件或连接因超过材料强度而破坏&#xff0c;或因过度变形…

安捷伦E4433B信号发生器

E4433B Agilent E4433B ESG-D系列 4G信号发生器安捷伦250kHz-4GHz 品  牌&#xff1a; Agilent 简单介绍 频率范围&#xff1a; E4430B 250K-1GHz E4431B 250K-2GHz E4432B 250K-3GHz E4433B 250K-4GHz 18320918653 供单信道和多信道CDMA用的测量卡用于I和Q的20 MH…

第六章 建造者模式

文章目录 前言一、传统方式解决盖房子需求完整代码抽象房子类 AbstractHouse实现子类 普通房子实现子类 高楼大厦客户端盖房子 二、引入建造者模式建造者模式的四个角色&#xff1a; 产品、抽象建造者、具体建造者、指挥者完整代码House类 (产品角色)抽象父类&#xff08;抽象建…

Node内置模块 【Event事件模块】

文章目录 &#x1f31f;前言&#x1f31f;Event事件模块&#x1f31f;EventEmitter类&#x1f31f;加载events模块&#x1f31f;实例化eventEmitter对象 &#x1f31f;事件方法列表&#x1f31f;使用事件&#x1f31f;异步与同步 &#x1f31f;写在最后 &#x1f31f;前言 哈喽…

ZLMeidiaKit实现推流时(FFmpeg推rtmp流)时非127.0.0.1被拒绝需要鉴权的解决方式

场景 开源流媒体服务器ZLMediaKit在Windows上运行、配置、按需拉流拉取摄像头rtsp视频流)并使用http-flv网页播放: 开源流媒体服务器ZLMediaKit在Windows上运行、配置、按需拉流拉取摄像头rtsp视频流)并使用http-flv网页播放_霸道流氓气质的博客-CSDN博客 在上面搭建ZLMedia…

CE作业(3)

1.基于域名[www.openlab.com](http://www.openlab.com)可以访问网站内容为 welcome to openlab!!! ​ 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c;基于[www.openlab.com/student](http://www.openlab.com/student) 网站访问学生信息&…

windows和linux上证书的增删查

文章目录 引言windows上对个人证书的增删查创建证书证书的查找证书的删除证书的安装 Linux上对个人证书的增删查创建证书证书的安装证书的查看证书的删除 Linux上对系统证书的增删查 引言 PS: 我之前看过《图解密码技术》&#xff0c;已经对证书这些概念有基本的了解&#xff…

Docker容器---dockerfile简介

Docker容器---dockerfile简介 一、dockerfile概念1、dockerfile介绍2、基于dockerfile创建3、docker镜像加载原理 二、镜像的创建1、基于现有镜像创建2、基于本地模板创建3、基于dockerfile创建 三、Dockerfile编写1、dockerfile操作指令&#xff08;1&#xff09;FROM 镜像&am…

9. 自注意力机制(Self-attention Part2)

P27 自注意力机制&#xff08;Self-attention Part2&#xff09; 视频链接 P27 自注意力机制&#xff08;Self-attention Part2&#xff09; 计算流程&#xff1a; Multi-head&#xff1a; 应用&#xff1a;

数据结构入门篇:第一篇

数据结构入门篇&#xff1a;第一篇 时间复杂度 数据结构入门篇&#xff1a;第一篇1.时间复杂度2.时间复杂度的练习总结 &#x1f914;首先&#xff0c;为什么要学数据结构&#xff1f; 数据结构的概念&#xff1a;在内存中对数据进行管理&#xff1b; 数据结构的学习能让我们在…