Spring之IoC

Spring的设计理念和整体架构

一句话概括就是:Spring是一个轻量级的、非侵入式的控制反转(IOC)和面向切面(AOP)的框架。

设计理念:
  1. 松散耦合: Spring鼓励开发者编写松散耦合的代码,通过依赖注入和接口抽象等方式来减少组件之间的紧耦合性。这有助于提高代码的可维护性和可测试性。

  2. 依赖注入(DI): Spring的核心特性之一是依赖注入,它允许开发者将对象之间的依赖关系通过配置文件或注解来声明,而不是在代码中硬编码依赖。这使得代码更加灵活和可配置。

  3. 面向切面编程(AOP): Spring支持AOP,允许开发者定义切面和通知,以实现横切关注点的重用,如日志记录、事务管理等。

  4. 声明式事务管理: Spring提供了声明式事务管理的支持,允许将事务配置为注解或XML配置,从而简化了事务管理的实现。

  5. 模块化: Spring框架被分为多个模块,每个模块提供特定的功能,如Spring核心容器、数据访问/集成、Web开发等。这种模块化的设计使得开发者可以根据需要引入特定的功能。

  6. 轻量级容器: Spring框架本身是非常轻量级的,不需要依赖大量外部库。它提供了自己的容器,用于管理应用程序中的对象。

主要模块:

Spring分模块存在,除了最核心的Spring Core Container(Beans、Core、Context和SpEl)之外,其他都是可选的。

七大主要模块:
  1. Spring Core:Spring 核⼼,它是框架最基础的部分,提供 IOC 和依赖注⼊ DI 特性。

  2. Spring Context:Spring 上下⽂容器,它是 BeanFactory 功能加强的⼀个⼦接⼝。

  3. Spring Web:它提供 Web 应⽤开发的⽀持。

  4. Spring MVC:它针对 Web 应⽤中 MVC 思想的实现。

  5. Spring DAO:提供对 JDBC 抽象层,简化了 JDBC 编码,同时,编码更具有健壮性。

  6. Spring ORM:它⽀持⽤于流⾏的 ORM 框架的整合,⽐如:Spring + Hibernate、Spring + iBatis、Spring + JDO 的整合等。

  7. Spring AOP:即⾯向切⾯编程,它提供了与 AOP 联盟兼容的编程实现。

整体架构:

Spring框架的整体架构是分层的,各个层次的功能被组织成不同的模块,如下所示:

  1. 核心容器(Core Container): 核心容器包括BeansCoreContextExpression Language模块,用于提供基本的IoC和DI功能。

  2. 数据访问/集成(Data Access/Integration): 这些模块包括JDBCORMJMSTransactions等,用于处理数据访问和集成外部系统。

  3. Web层(Web): Spring提供了多个Web开发相关的模块,如WebWeb-MVCWeb-Socket等,用于构建Web应用程序。

  4. AOP和Instrumentation(Aspect-Oriented Programming): 这些模块包括AOPAspectsInstrumentation等,用于支持AOP编程和性能监控。

  5. 消息(Messaging): 这些模块包括JMSAMQP等,用于处理消息传递。

  6. 测试(Testing): Spring提供了Test模块,用于编写和运行单元测试和集成测试。

Spring IoC 

IoC的基础概念

IoC(Inversion of Control): IoC是一种设计原则,它反转了传统的控制流。在传统的编程中,应用程序通常负责控制对象的创建和生命周期。而在IoC中,控制权被反转,应用程序不再负责直接创建和管理对象,而是将这些职责委托给一个容器或框架。这个容器负责实例化、组装和管理对象,使得应用程序的组件更加解耦、可维护和可扩展。举个简单的例子,从前要什么自己创建,现在要什么,spring容器给。

DI(Dependency Injection): DI是IoC的一种实现方式,它是IoC的一种具体形式。DI指的是通过将对象的依赖关系注入到对象中,而不是由对象自己创建或查找依赖关系。这可以通过构造函数注入、方法注入或属性注入来实现。DI的目的是降低组件之间的耦合性,使它们更容易被替换、测试和维护。关于DI最简单的例子就是Setter了。

IoC的设计与实现

Spring Ioc容器的设计中,可以看到两个主要的容器系列:简单容器BeanFactory和高级容器ApplicationContext。

简单容器BeanFactory

简单模拟下BeadFactory演示IoC的设计:

  1. 创建配置文件,包含BeanDefinition的信息。

    user:com.elaine.myspring.ioc.beanfactory.bean.User
  2. 创建一个BeanDefinition类,定义bean的属性。

    public class BeanDefinition {private String beanName;
    ​private Class beanClass;
    ​public String getBeanName() {return beanName;}
    ​public void setBeanName(String beanName) {this.beanName = beanName;}
    ​public Class getBeanClass() {return beanClass;}
    ​public void setBeanClass(Class beanClass) {this.beanClass = beanClass;}
    }
  3. 创建资源加载器ResourceLoader,用来加载配置文件中的配置。

    /*** 载入配置文件,通过BeanDefinition解析加载*/
    public class ResourceLoader {public static Map<String, BeanDefinition> getResource() {Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>(16);Properties properties = new Properties();try {InputStream inputStream = ResourceLoader.class.getResourceAsStream("/beans.properties");properties.load(inputStream);// 迭代遍历配置文件Iterator<String> iterator = properties.stringPropertyNames().iterator();while (iterator.hasNext()) {String key = iterator.next();String className = properties.getProperty(key);BeanDefinition beanDefinition = new BeanDefinition();beanDefinition.setBeanName(key);Class clazz = Class.forName(className);beanDefinition.setBeanClass(clazz);// 加载资源beanDefinitionMap.put(key, beanDefinition);}inputStream.close();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return beanDefinitionMap;}
    }
    ​
  4. 创建对象注册器BeanRegister,注册bean到container中。

    public class BeanRegister {// 假设所有对象都是单例的,用一个单例map缓存private Map<String, Object> singletonMap = new HashMap<>();
    ​/*** 获取单例bean* @param beanName* @return*/public Object getSingletonBean(String beanName) {return singletonMap.get(beanName);}
    ​/*** 注册单例bean* @param beanName* @param bean*/public void registerSingletonBean(String beanName, Object bean) {if(singletonMap.containsKey(beanName)) {return;}singletonMap.put(beanName, bean);}
    }
  5. 创建对象工厂BeanFactory,初始化需要完成资源的加载,对象注册器的创建。

    public class BeanFactory {private BeanRegister beanRegister;
    ​private Map<String, BeanDefinition> map = new HashMap<>();
    ​public BeanFactory(){// 创建bean注册器beanRegister = new BeanRegister();// 加载资源this.map = new ResourceLoader().getResource();}
    ​/*** 获取bean* @param beanName* @return*/public Object getBean(String beanName) {Object bean = beanRegister.getSingletonBean(beanName);if (bean != null) {return bean;}return createBean(map.get(beanName));}
    ​/*** 创建bean* @param beanDefinition* @return*/private Object createBean(BeanDefinition beanDefinition) {try {Object bean = beanDefinition.getBeanClass().newInstance();beanRegister.registerSingletonBean(beanDefinition.getBeanName(), bean);return bean;} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return null;}
    }
  6. 测试验证。

    public class TestUser {@Testpublic void beanFactory() {BeanFactory beanFactory = new BeanFactory();
    ​// 第一次获取,通过反射User user = (User) beanFactory.getBean("user");user.sayHello();
    ​// 第二次获取,通过缓存User user1 = (User) beanFactory.getBean("user");user.sayHello();
    ​// 所有对象都是单例的前提下,是同一个对象System.out.println(user1 == user);}
    }
高级容器ApplicationContext
  • ApplicationContext继承自BeanFactory,拥有更多的功能和特性,包括国际化、事件传播、资源访问等。

  • 和BeanFactory的延迟加载不同,ApplicationContext会在容器启动时就实例化和初始化所有的bean。

  • 支持更丰富的配置方式,包括XML配置、注解、java配置等,并且支持自动扫描并注册bean。

ApplicationContext通过读取xml配置的形式获取bean:

public class MySpringApplication {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");Product product = (Product) applicationContext.getBean("product");System.out.println(product.getId());}
}
IoC容器工作过程

Spring 的 IOC 容器⼯作的过程,其实可以划分为两个阶段:容器启动阶段和Bean实例化阶段。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Maven Eclipse

Eclipse 提供了一个很好的插件 m2eclipse &#xff0c;该插件能将 Maven 和 Eclipse 集成在一起。 在最新的 Eclipse 中自带了 Maven&#xff0c;我们打开&#xff0c;Windows->Preferences&#xff0c;如果会出现下面的画面&#xff1a; 下面列出 m2eclipse 的一些特点&a…

景联文科技:3D点云标注应用场景和专业平台

3D点云技术之所以得到广泛发展和应用&#xff0c;主要是因为它能够以一种直观、真实和全面的方式来表示和获取现实世界中的三维信息。 3D点云的优势&#xff1a; 真实感和立体感&#xff1a;3D点云数据能够呈现物体的真实感和立体感&#xff0c;使观察者能够更直观地理解物体的…

[SRT]1.协议简介

1.简介 ​ 安全可靠传输协议(Secure Reliable Transport)简称SRT&#xff0c;是一种基于UDT协议的开源互联网传输协议&#xff0c;Haivision和Wowza合作成立SRT联盟&#xff0c;管理和支持SRT协议开源应用的组织&#xff0c;这个组织致力于促进视频流解决方案的互通性&a…

淘宝天猫店铺所有商品数据接口,淘宝API接口

获取淘宝店铺所有商品数据接口的步骤如下&#xff1a; 获取授权&#xff1a;使用 OAuth 2.0 协议对应用进行授权&#xff0c;以便能够访问店铺的商品信息。获取店铺信息&#xff1a;使用淘宝 API 的 taobao.shop.get 接口&#xff0c;传入店铺的 user_id 参数&#xff0c;获取…

工矿企业电力运维云平台:提升效率与降低成本的关键

针对工矿企业用户&#xff0c;聚焦供配电领系统“安全监控、能耗管理、智能运维” 的三大需求&#xff0c;研发推出了“电易云”--智慧电力物联网&#xff0c;为工矿企业用户提供智慧电力数字化解决方案及数据服务&#xff0c;实现供配电系统的数字化、云端化、智能化、绿色化&…

el-select的el-option添加操作按钮插槽后实现勾选与按钮操作分离

这里我在el-option的选项文字后面添加了两个svg按钮&#xff08;编辑和删除&#xff09;&#xff1a;如图 当我们点击el-option时无法区分是勾选el-option还是点击了el-option选项文字后面的按钮&#xff0c;其实只要在后面的编辑和删除的操作按钮的click事件上面添加.native.…

多列等高实现

预期效果 多列等高,左右两列高度自适应且一样,分别设置不同背景色效果预览: 分别由6种方法实现 1、使用padding + margin + overflow 实现多列等高效果,具有良好的兼容性; 2、border实现多列等高,左边框宽度为200px,左列浮动,伪元素清除浮动; 3、父元素线性渐变背景色…

Redis - php通过ssh方式连接到redis服务器

1.应用场景 主要用于使用php通过ssh方式连接到redis服务器&#xff0c;进行一些操作. 2.学习/操作 1.文档阅读 chatgpt & 其他资料 SSH - 学习与实践探究_ssh应用场景 2.整理输出 2.1 是什么 TBD 2.2 为什么需要「应用场景」 TBD 2.3 什么时候出现「历史发展」 TBD 2.4 …

排序算法-快速排序法(QuickSort)

排序算法-快速排序法&#xff08;QuickSort&#xff09; 1、说明 快速排序法是由C.A.R.Hoare提出来的。快速排序法又称分割交换排序法&#xff0c;是目前公认的最佳排序法&#xff0c;也是使用分而治之&#xff08;Divide and Conquer&#xff09;的方式&#xff0c;会先在数…

Java架构师概要设计

目录 1 导学2 概要设计之任务和方法2.1 继续架构设计2.2 继续技术选型2.3 确定技术栈2.4 架构原型实现与验证2.5 技术预研2.6 分服务分模块2.7 初步设计应用基础框架2.8 定义基本API2.9 定义实体对象2.10 定义数据库表结构3 构建项目工程和环境4 代码组件的关系5 总结1 导学 本…

042:mapboxGL点击某feature点,使其为中心点

第042个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中通过鼠标点击某feature点,让其成为中心点。这里用到了click事件和flyTo的方法。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共113行)相关API参…

scratch保护环境 2023年5月中国电子学会图形化编程 少儿编程 scratch编程等级考试一级真题和答案解析

目录 scratch保护环境 一、题目要求 1、准备工作 2、功能实现 二、案例分析

Premiere Pro 2024 (Pr2024)最新中文安装版

Premiere Pro 2024是一款由Adobe公司开发的专业的视频剪辑软件&#xff0c;它可以帮助用户导入和编辑视频&#xff0c;添加各种效果&#xff0c;并将素材导出到任何目标。 该软件具有以下特点&#xff1a; 支持各种视频格式&#xff1a;Premiere Pro 2024可以处理各种视频格式…

ChatGPT AIGC 高效办公自动化案例

根据业务员姓名查找对应月份的科目成绩。 我们让ChatGPT AIGC来完成Excel公式。 Prompt:有一个表格A列为姓名,B列为语文,C列为数学,请根据J2单元格的姓名 ,查找出对应的数学成绩,请写出函数来完成 将生成的vlookup函数公式=VLOOKUP(J2, A:C, 3, FALSE)复制到表格中进行验…

塑胶材料检测对激光焊机的作用

塑胶材料的激光焊接已经普遍用于各种零配件&#xff0c;而塑料的透光率是焊接工艺质量的一个重要指标。针对这类塑胶材料推出这款专门检测塑胶材料近红外透光率特性的透光率检测仪&#xff0c;对注塑件的透光率进行全画面扫描。 全球工业致力于贯彻绿色环保、节能减排发展理念&…

android studio 我遇到的Task :app:compileDebugJavaWithJavac FAILED问题及解决过程

前几天一个网友在学习我的一个小项目的时候&#xff0c;发现无法达到目的&#xff0c;在帮他解决问题的过程中发现他用的是最近的giraffe版本的as&#xff0c;我用的是老版本&#xff0c;没办法打开他的项目&#xff0c;没办法只能卸载我的as&#xff0c;安装了最近版的diraffe…

【FreeRTOS】【STM32】03 FreeRTOSConfig.h头文件简介与修改

基于[野火]《FreeRTOS%20内核实现与应用开发实战—基于STM32》.pdf FreeRTOSConfig.h头文件是FreeRTOS各项功能的打开与关闭 FreeRTOSConfig.h头文件简介 之前也说过了&#xff0c;FreeRTOSConfig.h文件可以添加在工程中任意文件夹&#xff0c;只需要在路径中添加好了就行。…

【C++】STL总结:理解六大核心组件、各个组件主要功能

文章目录 六大核心组件的关联性1.容器2.迭代器3.算法4. 仿函数 / 函数对象5. 适配器 / 包装器6. 空间配置器 六大核心组件的关联性 1.容器 &#x1f517;&#x1f449;点击跳转 2.迭代器 &#x1f517;&#x1f449;点击跳转 3.算法 &#x1f517;&#x1f449;点击跳转 …

电脑图片jpeg怎么转jpg格式?jpeg和jpg的转换方法

很多平台对上传的图片格式都有严格的要求&#xff0c;当我们遇到图片格式不对的时候&#xff0c;就需要改图片格式了&#xff0c;下面以jpeg转jpg&#xff08;在线图片格式转换器&#xff08;jpg、png、gif、webp、bmp、tiff&#xff09;-压缩图&#xff09;为例子&#xff0c;…

解决 Centos 安装 Python 3.10 的报错: Could not import runpy module

操作环境&#xff1a;CentOS 7、Gcc 4.8.5、Python 3.10.0 系统上已经有 2.x&#xff0c;3.6 版本的 Python 了&#xff0c;但是还是想装一个 3.10 的。因为刚写的脚本文件是较高版本的&#xff0c;在 3.6 上无法正常运行&#xff0c;Python 语法不是很了解&#xff0c;只能从…