1. Bean 的作用域

1.1 观看案例

现在有一个公共 Bean

@Component
public class UserBean {
    @Bean
    public User user1() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        user.setAge(18);
        return user;
    }
}

现在有一个用户1, 进行了修改的操作

@Controller
public class UserControllerA {
    @Autowired
    private User user1;
    public User getUser1() {
        User user = user1;
        System.out.println("用户1修改之前: "   user1);
        user.setName("王五");
        return user;
    }
}

现在有用户2, 进行读取操作

@Controller
public class UserControllerB {
    @Autowired
    private User user1;
    public User getUser1() {
        User user = user1;
        return user;
    }
}

打印用户1和用户2公共Bean的值

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        UserControllerA userControllerA = context.getBean("userControllerA",UserControllerA.class);
        User user = userControllerA.getUser1();
        System.out.println("用户1修改之后: "   user);
        UserControllerB userControllerB = context.getBean("userControllerB",UserControllerB.class);
        User user1 = userControllerB.getUser1();
        System.out.println("用户2读取到的: "   user1);
    }

运行结果

原因:

Spring 中 Bean 的作用域默认是 singleton 单例模式. 所有人使用的都是同一个对象.

1.2 作用域的定义

之前所说的作用域, 是在程序中定义的某个变量的某个区域就叫做作用域.这里的Bean作用域不同.

Bean 的作用域指: Bean在 Spring 整个框架中的某种行为模式,

比如 singleton 单例作用域, 就表示 Bean 在整个 Spring 中只有一份, 它是全局共享的, 那么当其他人修改了这个值之后, 那么另一个人读取到的就是被修改的值.

1.3 Bean 的 6 种作用域

Spring 容器在初始化一个 Bean 的示例时, 同时会指定该实例的作用域.

Spring 有 6 种作用域.

  • singleton: 单例作用域
  • prototype: 原型作用域 (多例作用域)
  • request: 请求作用域
  • session: 回话作用域
  • application: 全局作用域
  • websocket: HTTP WebSocket 作用域

3~6 这四种是 Spring MVC 中的值.

1.4 如何设置 Bean 的作用域

@Scope 既可以用于方法注解, 也可以用于类注解

① @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

② @Scope(“prototype”)

注意事项:

如果是 @Bean @Scope , 这里的@Scope 就不能写成类注解的方式了.

2. Bean 的生命周期

2.1 Bean 的执行流程

  • 启动 Spring 容器
  • 加载 Spring 配置文件
  • 加载 Spring 配置文件中的 Bean, 或根据配置文件中的组件根路径, 进行 Bean 对象的扫描(扫描@Controller…)
  • Bean 注册到 Spring 中
  • 执行完毕,执行销毁操作

2.2 Bean 生命周期

Bean 的生命周期分为 5 大部分:

实例化 Bean (为Bean分配内存空间)

设置属性 (Bean 进行初始化注入)

Bean 初始化 (一系列准备工作)

① 各种通知 (xxxAware)

② 执行初始化前置方法 BeanPostProcessor

③ 执行 @PostConstruct 初始化方法

④ 执行 init-mehtod 初始化方法

⑤ 执行初始化后置方法 BeanPostProcessor

使用 Bean

销毁 Bean

  • ① 执行销毁前方法 @PreDestory
  • ② 如果有接口 DisposableBean, 执行实现方法
  • ③ 执行销毁前的方法 destory-method

2.3 生命周期演示代码

主要代码

package com.wwzz.util;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class BeanLifeComponent implements BeanNameAware {
    @Override
    public void setBeanName(String s) {
        System.out.println("执行通知: BeanNameAware "   s);
    }
    @PostConstruct
    public void postConstruct(){
        System.out.println("执行 @PostConstruct");
    }
    public void init() {
        System.out.println("执行 init-method");
    }
    @PreDestroy
    public void preDestroy(){
        System.out.println("执行 @PreDestroy");
    }
    public void destroy() {
        System.out.println("执行 destroy");
    }
}

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"> <!-- 配置 Spring 扫描的根路径(此根路径下的所有 Spring 存对象的注解才能生效) --> <content:component-scan base-package="com.wwzz"></content:component-scan> <beans> <bean id="beanLifeComponent" class="com.wwzz.util.BeanLifeComponent" init-method="init" destroy-method="destroy"></bean> </beans></beans><?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">
    <!-- 配置 Spring 扫描的根路径(此根路径下的所有 Spring 存对象的注解才能生效) -->
    <content:component-scan base-package="com.wwzz"></content:component-scan>
    <beans>
        <bean id="beanLifeComponent" class="com.wwzz.util.BeanLifeComponent" init-method="init" destroy-method="destroy"></bean>
    </beans>
</beans>

测试运行

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        BeanLifeComponent beanLifeComponent = context.getBean("beanLifeComponent",BeanLifeComponent.class);
        context.destroy();
    }

查看结果

到此这篇关于Java深入讲解Bean作用域与生命周期的文章就介绍到这了,更多相关Bean作用域与生命周期内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Java深入讲解Bean作用域与生命周期的更多相关文章

  1. ios – 不同作用域中相同命名常量的链接器错误

    我有一个名为“ID_KEY”的常量,它在3个单独的.m文件的顶部声明,其中没有包含其他文件.声明如下:而其他两个类也是如此.但是我收到一个链接器错误抱怨同名的多个定义.我的问题是为什么链接器抱怨这个呢?

  2. 15.6 Swift局部引用

    /**局部引用和全局引用1.作用域2.生命周期*/varref:Int=Int.init/**定义一个变量或者常量,如果不是可选类型的话,一定要有初始值。所谓的局部引用就是在代码块里面的引用就是局部引用。作用域生命周期都在该代码块中;离它最近的括号*/iftrue{varref:Student=Student.initref.name="ZHangsan"}//超出作用域啦//ref.name="ZHangsan"

  3. android – 在Jelly Bean平板电脑中隐藏系统栏(生根)

    我有一个AndroidJellyBean平板电脑已经扎根并且试图运行一个应用程序,其中包含隐藏系统栏的代码,但它没有被隐藏,任何人都可以帮助我解决这个问题.获取终端输出:结果包(00000000’….’)虽然我正在获得许可的祝酒:超级用户日志屏幕截图:解决方法当引入ICS时,systemUI类的进程ID从79更改为42.下面的代码适用于您的应用可能正在运行的任何Android版本.

  4. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  7. Java实现世界上最快的排序算法Timsort的示例代码

    Timsort 是一个混合、稳定的排序算法,简单来说就是归并排序和二分插入排序算法的混合体,号称世界上最好的排序算法。本文将详解Timsort算法是定义与实现,需要的可以参考一下

  8. Java日期工具类的封装详解

    在日常的开发中,我们难免会对日期格式化,对日期进行计算,对日期进行校验,为了避免重复写这些琐碎的逻辑,我这里封装了一个日期工具类,方便以后使用,直接复制代码到项目中即可使用,需要的可以参考一下

  9. Java设计模式之模板方法模式Template Method Pattern详解

    在我们实际开发中,如果一个方法极其复杂时,如果我们将所有的逻辑写在一个方法中,那维护起来就很困难,要替换某些步骤时都要重新写,这样代码的扩展性就很差,当遇到这种情况就要考虑今天的主角——模板方法模式

  10. Java 中 Class Path 和 Package的使用详解

    这篇文章主要介绍了Java 中 Class Path和Package的使用详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部