• Bean的作用域和生命周期


    在这里插入图片描述


    🍌 一.Bean的作用域

    Bean的作用域其实就是bean在spring整个框架中的某种行为,而一般bean在spring中默认是单例模式,下面一起来看看bean的所有作用域吧!

    🍓 1.Bean的六个作用域

    🍉 1.1.singleton(单例模式)

    通常无状态(bean的状态不需要修改)下的bean就会使用该作用域,而且每一次注入的bean都是同一个bean;

    🍉 1.2.prototype(原型模式)

    原型模式其实就是相对于单例模式的多例模式,通常有状态的情况下使用该作用域,每一次注入的时候都会创建一个新的bean对象;

    🍉 1.3.request(请求作用域)

    这个是Spring MVC项目中独有的作用域,每一次http请求都会创建bean实例,类似于原型模式不过两种作用域发生在不同的项目里面;

    🍉 1.4.session(会话作用域)

    这个也是Spring MVC项目中的,在一个http session中都会共享一个bean实例,来记录一个用户的登录信息;

    🍉 1.5.application(全局作用域)

    这个也是Spring MVC项目中的,通常在一个http servlet Context中定义一个bean实例在Web应用的上下文中都是使用一个bean,这个作用域了解即可;

    🍉 1.6.websocket(HTTP WebSocket作用域)

    这个是Spring WebSocket项目里面的作用域,在一个http WebSocket的生命周期中,会定义一个bean,这个作用域了解即可;

    🍉 1.7.singleton(单例作用域)和application(全局作用域)

    区别:

    • singleton是Spring Core中的作用域,application是Spring Web中的作用域;
    • singleton作用于IoC容器,而application作用于Servlet容器;

    🍓 2.设置Bean作用域

    @Component
    public class UserBeans {
        @Bean(name = {"userinfo"}) 
        public User getUser(){
            User user = new User();
            user.setId(1);
            user.setName("小狗");
            return user;
        }
    }
    @Component
    public class BeanScope1 {
        @Autowired
        private User userinfo;
    
        public User getUser(){
            User user = userinfo;
            user.setName("张三");
            return user;
        }
    }
    
    @Component
    public class BeanScope2 {
        @Autowired
        private User userinfo;
    
        public User getUser(){
    
            return userinfo;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
            BeanScope1 beanScope1 = context.getBean(BeanScope1.class);
            User user1 = beanScope1.getUser();
            System.out.println("BeanScope1:" + user1);
            BeanScope2 beanScope2 = context.getBean(BeanScope2.class);
            User user2 = beanScope2.getUser();
            System.out.println("BeanScope2:" + user2);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    在这里插入图片描述
    通过这个案例,就体现出了bean的单例模式,两次获得到的都是同一个bean,当第一个发生了改变,第二个也随之发生改变;
    而想要修改作用域,就需要使用@Scope注解来进行设置,@Scope既可以修饰方法也可以修饰类,这里有两种设置修改bean的作用域的方式:

    🍉 2.1.直接设置值

    @Scope(“prototype”)直接加在@Bean标签的下面就可以了

    @Component
    public class UserBeans {
        @Bean(name = {"userinfo"})
        @Scope("prototype")
        public User getUser(){
            User user = new User();
            user.setId(1);
            user.setName("小狗");
            return user;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这样就作用域就变成了原型模式就是每次读取bean都会获得到一个新的bean对象
    在这里插入图片描述
    就会发现原本的小狗并没有发生改变!

    🍉 2.2.使用枚举设置

    这样的设置方式是类似于枚举常量一样的形式,@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)也是和上面一样的写法

    @Component
    public class UserBeans {
        @Bean(name = {"userinfo"})
        @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
        public User getUser(){
            User user = new User();
            user.setId(1);
            user.setName("小狗");
            return user;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11


    两种方法效果都是一样的,都可以将单例模式改成原型模式!


    在这里插入图片描述

    🍌 二.Bean的生命周期

    先来看一下Bean的执行流程(Spring的执行流程):
    启动Spring容器->根据xml配置完成Bean的初始化->通过五大类注解存储Bean到Spring容器中->将Bean注入到需要的类中;
    了解了这个再来看一下Bean的生命周期:
    Bean的生命周期其实就是Bean对象从诞生到销毁的整个过程,就成为生命周期,而Bean的生命周期可以分为5个部分,可以一起来看一下:

    🍓 1.实例化Bean

    实例化不是初始化,就是为bean分配内存空间;

    🍓 2.设置属性

    设置属性就是对象注入;

    🍓 3.Bean初始化

    🍉 3.1.执行各种通知

    执行Aware通知;

    🍉 3.2.执行初始化的前置方法

    🍉 3.3.执行构造方法

    执行构造方式有两种方式:

    • 执行@PostConstruct;
    • 执行init-method方法;

    这两种都是进行初始化,只不过是不同时代的产物罢了,而注解的优先级会高于init-method方法,不过一般不会两种都使用;

    🍉 3.4.执行初始化的后置方法

    🍓 4.使用Bean

    🍓 5.销毁Bean

    销毁bean的方法:@PreDestroy和destroy-method方法,这也和上面的初始化方式是同样的道理,只是不同时代的产物,另外如果有实现接口,需要重写DisposableBean接口方法。


    在这里插入图片描述

  • 相关阅读:
    uniapp树形层级选择器
    Java四舍五入
    Abbkine ExKine 总蛋白提取试剂盒实验建议&FAQ
    AJAX的Promise(原理)
    2020 号门牌,总共需要多少个字符 2
    RabbitMQ--延迟队列--使用/原理
    [ vulhub漏洞复现篇 ] Hadoop-yarn-RPC 未授权访问漏洞复现
    nxp电源管理芯片:电源管理芯片的制造与采样规格
    数学建模:模糊综合评价分析
    前端基础建设与架构10 代码拆分和按需加载:缩减 bundle size,把性能做到极致
  • 原文地址:https://blog.csdn.net/qq_58266033/article/details/125787050