编织Spring魔法:解读核心容器中的Beans机制【beans 一】

news2024/11/18 7:40:44

欢迎来到我的博客,代码的世界里,每一行都是一个故事


在这里插入图片描述

编织Spring魔法:解读核心容器中的Beans机制【beans 一】

    • 前言
    • 什么是Spring核心容器
    • Beans的生命周期管理:
      • 初始化和销毁方法:
      • 各种作用域:
    • beans的配置方式
      • 1. XML配置:
      • 2. Java注解配置:
      • 3. JavaConfig方式:
    • 依赖注入的实现
      • 1. 构造器注入:
      • 2. Setter 方法注入:
      • 3. 接口注入:
    • 循环依赖
    • beans的AOP支持

前言

在现代软件开发领域,Spring框架已经成为构建强大、灵活、可维护应用程序的不二选择。而Spring的核心容器是这一框架的心脏,Beans则是其中最为关键的组成部分。本文将带您深入探索这个令人着迷的世界,解锁Beans的神秘面纱,让您更深刻地理解Spring的精髓。

什么是Spring核心容器

Spring核心容器是Spring框架的核心部分,它提供了一种管理和组织应用组件的方式。核心容器包括以下四个模块:

  1. Beans(Bean模块): 这是Spring框架的基础,负责创建、管理和装配Java对象(称为Beans)。Beans是由Spring容器管理的应用组件,这些组件在Spring应用程序中相互协作。

  2. Core(核心模块): 提供了Spring框架的核心功能,包括IoC容器的基本功能。这部分包括IoC(控制反转)和DI(依赖注入)的实现。

  3. Context(上下文模块): 构建于Core模块之上,为应用程序对象定义了一种访问方式。它为开发者提供了更广泛的功能,如国际化、事件传播、应用程序层面的配置等。

  4. Expression Language(表达式语言模块): 允许在运行时查询和操作对象图,通常用于查询和操作Spring Beans。

容器的角色和功能:

  • 实例化: 容器负责实例化应用程序中的对象(Beans)。这意味着开发者不再需要直接使用new关键字来创建对象。

  • 配置: 容器允许开发者通过配置文件或注解来描述组件之间的关系和如何创建这些组件。

  • 组装: 容器负责将不同组件组装在一起,形成一个完整的应用程序。

  • 管理生命周期: 容器管理Beans的生命周期,包括创建、初始化、使用、销毁等阶段。

IoC和DI的基本概念:

  • IoC(控制反转): 是一种设计模式,它将传统的程序控制流反转过来,由容器控制应用程序的流程。在Spring中,IoC由容器负责实例化、装配和管理Beans。

  • DI(依赖注入): 是IoC的一种实现方式,它指的是通过容器将依赖关系注入到对象中,而不是在对象内部创建它们。这样做的好处是提高了组件的可重用性和松耦合性。

总体而言,Spring核心容器通过IoC和DI的实现,提供了一种灵活、可维护和可扩展的方式来组织和管理Java应用程序的组件。

在Spring框架中,Beans的生命周期由Spring容器管理,包括初始化和销毁阶段。同时,Spring提供了不同的作用域,其中最常见的是singleton和prototype。

Beans的生命周期管理:

  1. 实例化: 当Spring容器启动时,它会通过反射或工厂方法等方式创建Bean的实例。

  2. 属性设置: 容器通过依赖注入将配置的属性值或引用设置到Bean中。

  3. BeanPostProcessor的前置处理(可选): 如果配置了BeanPostProcessor,它将在Bean的初始化前后执行自定义的处理逻辑。

  4. 初始化: 如果Bean实现了InitializingBean接口,或者在配置中通过init-method指定了初始化方法,容器将调用该方法来完成初始化。

  5. 使用: Bean可以被应用程序正常使用。

  6. BeanPostProcessor的后置处理(可选): 如果配置了BeanPostProcessor,它将在Bean的初始化前后执行自定义的处理逻辑。

  7. 销毁: 如果Bean实现了DisposableBean接口,或者在配置中通过destroy-method指定了销毁方法,容器将在Bean被销毁时调用该方法。

初始化和销毁方法:

在配置Bean时,可以通过以下两种方式指定初始化和销毁方法:

  • 通过接口: 实现InitializingBean接口来定义初始化逻辑,实现DisposableBean接口来定义销毁逻辑。

    public class MyBean implements InitializingBean, DisposableBean {
        // 初始化逻辑
        @Override
        public void afterPropertiesSet() throws Exception {
            // ...
        }
    
        // 销毁逻辑
        @Override
        public void destroy() throws Exception {
            // ...
        }
    }
    
  • 通过配置: 在XML或Java配置中,使用init-methoddestroy-method属性来指定初始化和销毁方法的名称。

    <bean id="myBean" class="com.example.MyBean" init-method="init" destroy-method="cleanup"/>
    

各种作用域:

  1. Singleton(单例): 在整个Spring容器中,只存在一个Bean的实例。默认情况下,所有的Bean都是单例的。

    <bean id="mySingletonBean" class="com.example.MyBean" scope="singleton"/>
    
  2. Prototype(原型): 每次通过容器获取Bean时,都会创建一个新的实例。

    <bean id="myPrototypeBean" class="com.example.MyBean" scope="prototype"/>
    
  3. Request(请求): 在每个HTTP请求中,容器会为Bean创建一个新的实例。

  4. Session(会话): 在每个用户会话中,容器会为Bean创建一个新的实例。

  5. Global Session: 类似于Session作用域,但用于Portlet应用。

选择适当的作用域取决于应用程序的需求和Bean的性质。

beans的配置方式

在Spring框架中,有多种方式可以配置Beans,包括XML配置、Java注解配置和JavaConfig方式。下面是每种配置方式的简要介绍:

1. XML配置:

使用XML配置是Spring最传统和最常见的方式之一。在XML配置中,开发者可以定义Beans及其属性、依赖关系等。以下是一个简单的XML配置示例:

<!-- 配置一个名为 "myBean" 的Bean -->
<bean id="myBean" class="com.example.MyBean">
    <property name="property1" value="someValue"/>
    <property name="property2" ref="anotherBean"/>
</bean>

<!-- 配置另一个Bean -->
<bean id="anotherBean" class="com.example.AnotherBean"/>

2. Java注解配置:

使用Java注解配置,开发者可以通过在Java类上添加注解来描述Beans。常用的注解包括@Component@Service@Repository等,用于标识不同类型的组件。以下是一个简单的Java注解配置示例:

@Component
public class MyBean {
    private String property1;
    private AnotherBean property2;

    // 省略构造函数和其他方法

    @Value("someValue")
    public void setProperty1(String property1) {
        this.property1 = property1;
    }

    @Autowired
    public void setProperty2(AnotherBean property2) {
        this.property2 = property2;
    }
}

3. JavaConfig方式:

JavaConfig方式允许开发者使用Java类来配置Spring应用程序,而不需要XML文件。通过创建一个带有@Configuration注解的类,并在其中使用@Bean注解来定义Beans,可以实现JavaConfig。以下是一个简单的JavaConfig配置示例:

@Configuration
public class AppConfig {

    @Bean
    public MyBean myBean() {
        MyBean bean = new MyBean();
        bean.setProperty1("someValue");
        bean.setProperty2(anotherBean());
        return bean;
    }

    @Bean
    public AnotherBean anotherBean() {
        return new AnotherBean();
    }
}

在上述示例中,AppConfig类通过@Configuration注解表示它是一个配置类,@Bean注解用于定义Beans。然后,可以通过将这个配置类传递给AnnotationConfigApplicationContext来加载配置。

每种配置方式都有其适用的场景和优势,开发者可以根据项目需求和个人偏好选择合适的配置方式。通常,大型项目可能会结合使用这些配置方式,以便更好地组织和管理应用程序的组件。

依赖注入的实现

依赖注入(Dependency Injection,DI)是Spring框架的核心特征之一,它通过不同的方式实现将依赖对象注入到目标对象中。以下是三种常见的依赖注入方式的实现:

1. 构造器注入:

构造器注入是通过目标对象的构造方法来注入依赖的方式。在Spring中,通过在类的构造方法上添加 @Autowired 注解来实现构造器注入。

public class MyClass {

    private MyDependency myDependency;

    @Autowired
    public MyClass(MyDependency myDependency) {
        this.myDependency = myDependency;
    }
}

2. Setter 方法注入:

Setter 方法注入是通过目标对象的 setter 方法来注入依赖的方式。在Spring中,通过在对应的 setter 方法上添加 @Autowired 注解来实现Setter方法注入。

public class MyClass {

    private MyDependency myDependency;

    @Autowired
    public void setMyDependency(MyDependency myDependency) {
        this.myDependency = myDependency;
    }
}

3. 接口注入:

接口注入是通过目标对象实现一个接口,在接口中定义依赖的属性,然后Spring通过接口来注入依赖。

public interface MyDependencySetter {
    void setMyDependency(MyDependency myDependency);
}

public class MyClass implements MyDependencySetter {

    private MyDependency myDependency;

    @Override
    public void setMyDependency(MyDependency myDependency) {
        this.myDependency = myDependency;
    }
}

这三种注入方式在Spring框架中都能够很好地工作,选择使用哪一种取决于具体的需求和设计偏好。通常而言,构造器注入在对象创建时一次性注入所有依赖,Setter 方法注入提供了更灵活的注入方式,而接口注入可以用于实现一些特定的接口,定义自己的注入规范。

循环依赖

spring的三级缓存,以及循环依赖的形成和解决(详细)

beans的AOP支持

解锁Spring Boot AOP的魔力:优雅地管理交叉关注点

深入理解Spring Boot AOP:CGLIB代理与JDK动态代理的完全指南

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

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

相关文章

【Bidomain建模范式:Pansharpening】

Bidomain Modeling Paradigm for Pansharpening &#xff08;泛锐化的Bidomain建模范式&#xff09; 泛锐化是一个具有挑战性的低层次视觉任务&#xff0c;其目的是学习光谱信息和空间细节之间的互补表示。尽管取得了显着的进步&#xff0c;现有的基于深度神经网络&#xff0…

JVM内存模型理解

1、首先理解下什么是 jvm 内存模型&#xff1f; jvm内存模型定义了Java虚拟机运行时如何组织和管理内存&#xff0c;规定了各个内存区域的作用、结构和交互方式&#xff0c;以及线程间的内存可见性、内存操作的原子性等行为&#xff0c;以支持Java程序的执行&#xff0c;即一种…

以角色为基础的软件开发团队建设

角色抽象作为一种载体&#xff0c;可以很好地进行软件工程知识体系和企业知识地图的组织&#xff0c;满足企业知识体系持续改进的需要&#xff0c;因此角色团队组建和建设也可以作为软件工程实施方法之一。 软件开发项目立项时&#xff0c;重要工作之一就是开发团队的组建&…

Spring Security 6.x 系列(13)—— 会话管理及源码分析(一)

一、会话概念 在实现会话管理之前&#xff0c;我们还是先来了解一下协议和会话的概念&#xff0c;连协议和会话都不知道是啥&#xff0c;还谈啥管理。 1.1 http 协议 因为我们现在的会话&#xff0c;基本上都是基于HTTP协议的&#xff0c;所以在讲解会话之前&#xff0c;我再…

openmediavault(OMV) (26)网络(1)ddns-go

简介 "ddns-go" 是一个动态域名解析(Dynamic DNS)工具,用于更新域名的IP地址。它可以自动检测你的公共IP地址,并将其更新到指定的域名解析服务商,以确保你的域名始终与最新的IP地址相匹配。 安装 hub.docker.com上下载ddns-go镜像 配置compose文件 --- versio…

使用 Process Explorer 和 Windbg 排查软件线程堵塞案例分享

目录 1、问题说明 2、线程堵塞的可能原因分析 3、使用Windbg和Process Explorer确定线程中发生了死循环 4、根据Windbg中显示的函数调用堆栈去查看源码&#xff0c;找到问题 4.1、在Windbg定位发生死循环的函数的方法 4.2、在Windbg中查看变量的值去辅助分析 4.3、是循环…

ModStartCMS v7.9.0 内容推荐支持,用户授权升级

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议&#xff0c;免费且不限制商业使用。 功能特性 丰富的模块市…

CMake入门教程【基础篇】HelloCMake

文章目录 概述核心实现代码示例使用技巧注意事项 总结 概述 CMake是一个强大的跨平台构建系统&#xff0c;广泛用于C和C项目。它使用简单的配置文件来生成标准的构建文件&#xff0c;从而使得构建过程跨平台且易于管理。本教程将通过一个“Hello World”示例&#xff08;命名为…

必看 | 如何用「八爪鱼RPA」搬迁旧帮助中心站点到「HelpLook」?

对于工具类产品而言&#xff0c;帮助中心的搭建是非常重要的&#xff1a;一个好用的帮助中心&#xff0c;不仅可以帮助用户快速找到所需内容&#xff0c;提升用户的满意度&#xff1b;还可以减轻客服人员的压力&#xff0c;为公司节约大量的人力资源。 以八爪鱼采集器的帮助中心…

【Leetcode】466. 统计重复个数

文章目录 题目思路代码 题目 466. 统计重复个数 思路 题目要求找出一个最大整数 m&#xff0c;使得经过 n2 个字符串 s2 组成的字符串能够被经过 n1 个字符串 s1 组成的字符串完全包含的次数。使用动态规划来记录每个位置匹配的情况&#xff0c;并通过循环节的分析来计算最…

安全数据交换系统:有效提升网间文件交换能力

各级政府部门和金融、能源、电力这些行业&#xff0c;以及一些大中型企业组织&#xff0c;为了保护内部的重要数据不外泄&#xff0c;普遍都采用了多网络并行的方式&#xff0c;也是做了网络隔离划分&#xff0c;不同的网络拥有不同的密级以及人员权限。然后再通过安全数据交换…

C++Qt6 哈夫曼编码求解 数据结构课程设计 | JorbanS

一、 问题描述 在进行程序设计时&#xff0c;通常给每一个字符标记一个单独的代码来表示一组字符&#xff0c;即编码。在进行二进制编码时&#xff0c;假设所有的代码都等长&#xff0c;那么表示 n 个不同的字符需要 位&#xff0c;称为等长编码。如果每个字符的使用频率相等&…

系列七、Ribbon

一、Ribbon 1.1、概述 Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具&#xff0c;是Netflix发布的一款开源项目&#xff0c;其主要功能是提供客户端的软件负载均衡算法和服务调用&#xff0c;Ribbon客户端组件提供一系列完善的配置项&#xff0c;例如&#xff1a…

免费证书Let’s Encrypt

免费SSL证书是一种用于保护网站数据传输安全的加密技术。它能够确保用户与网站之间的信息传输是加密的&#xff0c;防止被黑客窃取或篡改。随着网络安全意识的提高&#xff0c;越来越多的网站开始使用SSL证书来保护用户的隐私和数据安全。 在过去&#xff0c;SSL证书需要购买才…

OpenAI官方发布ChatGPT 提示词指南,六大策略让你玩转大语言模型!

OpenAI前段时间官方放出了自己的提示工程指南&#xff0c;从大模型小白到开发者&#xff0c;都可以从中消化出不少营养。看看全世界最懂大模型的人&#xff0c;是怎么写提示词的。官方给出了6 个大提示策略&#xff1a; 1、清晰的指令&#xff1a; 告诉AI你具体想要什么。比如…

ElasticSearch的DSL查询语法解析

Elasticsearch提供了基于ISON的DSL (Domain Specific Lanquage)来定义查询。 目录 一、常见查询类型 二、DSLQuery基本语法 三、全文检索查询 3.1 match查询&#xff1a;会对用户输入内容分词&#xff0c;常用于搜索框搜索 &#xff0c;语法&#xff1a; 3.2 multi match…

RK3568 学习笔记 : 解决 linux_sdk 编译 python 版本报错问题

前言 最近买了 【正点原子】 的 RK3568 开发板&#xff0c;下载了 开发板的资料&#xff0c;包括 Linux SDK&#xff0c;这个 Linux SDK 占用的空间比较大&#xff0c;扩展了一下 VM 虚拟机 ubuntu 20.04 的硬盘空间&#xff0c;编译才正常通过。 编译 RK3568 Linux SDK 时&am…

STM32存储左右互搏 SPI总线读写FRAM MB85RS2M

STM32存储左右互搏 SPI总线读写FRAM MB85RS2M 在中低容量存储领域&#xff0c;除了FLASH的使用&#xff0c;&#xff0c;还有铁电存储器FRAM的使用&#xff0c;相对于FLASH&#xff0c;FRAM写操作时不需要预擦除&#xff0c;所以执行写操作时可以达到更高的速度&#xff0c;其…

Postgresql源码(119)PL/pgSQL中ExprContext的生命周期

前言 在PL/pgSQL语言中&#xff0c;执行任何SQL都需要通过SPI调用SQL层解析执行&#xff0c;例如在SQL层执行表达式的入口&#xff1a; static bool exec_eval_simple_expr(PLpgSQL_execstate *estate,PLpgSQL_expr *expr,Datum *result,bool *isNull,Oid *rettype,int32 *re…

RK3568驱动指南|第九篇 设备模型-第95章 创建属性文件并实现读写功能实验1

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…