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.hqwc.cn/news/132322.html

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

相关文章

语音芯片基础知识 什么是语音芯 他有什么作用 发展趋势是什么

目录 一、语音芯片的简介 常见的语音芯片有哪些&#xff1f; 语音芯片的种类有很多&#xff0c;大体区分下来也就4个类别而已&#xff1a; 选型的经验说明如下&#xff1a; 推荐使用flash型语音芯片 一、语音芯片的简介 语音芯片基础知识&#xff1a; 什么是语音芯片&…

consumer罢工,几千万条im聊天数据积压在MQ中,解决思路

最近遇到一个线上问题&#xff0c;consumer出问题了&#xff0c;导致几千万条im聊天数据积压在MQ中几个小时&#xff0c;从下午五点多&#xff0c;积压到晚上十二点多。 遇到这种事一种解决办法是&#xff0c;修复consumer&#xff0c;让它慢慢消费。这样搞的话展示不了实力。 …

go 项目打包部署到服务器

1、window打包到Linux 步骤1 依次执行一下命令&#xff0c;就会得到一个exe 文件 步骤2 把打包的文件&#xff0c;放到服务器上&#xff08;可以使用FinalShell工具&#xff09; chmod x main # 执行这个命令&#xff0c;给main 文件添加 执行权限&#xff0c;然后执行 ls &…

书客、柏曼、爱德华哪款比较值得入手?三款台灯多维度测评

随着现在孩子的近视趋势越来越严峻&#xff0c;有很多家长开始意识到自己的孩子也出现了揉眼睛、时不时眯眯眼的情况。而台灯作为守护孩子用眼环境的必备用品&#xff0c;很多家长想给孩子购置一款护眼灯&#xff0c;却看见市面琳琅满目的款式根本不知道怎么购买。 所以今天为了…

3D模型格式转换工具HOOPS Exchange:模型数据自由导入和导出

HOOPS Exchange是一套高性能软件库&#xff0c;可以为软件开发人员提供导入和导出3D文件格式的能力。HOOPS Exchange导入3D数据后&#xff0c;会将3D数据转换为PRC格式存放到内存中&#xff0c;最后导出成为其他3D格式。&#xff08;点击申请HOOPS Exchange免费试用&#xff09…

docker 部署 xxl-job SpringBoot 整合 xxl-job 执行任务

概述 XXL-JOB是一个轻量级的分布式任务调度平台&#xff0c;具有以下特点&#xff1a; 调度模块&#xff1a;负责管理调度信息&#xff0c;发出调度请求&#xff0c;支持可视化和动态的操作&#xff0c;监控调度结果和日志&#xff0c;支持执行器Failover 执行模块&#xff1…

HashMap -- 调研

HashMap 调研 前言JDK1.8之前拉链法: JDK1.8之后JDK1.7 VS JDK1.8 比较优化了一下问题: HashMap的put方法的具体流程?HashMap的扩容resize操作怎么实现的?源码得到结论 小记概念&#xff1a; 什么是散列概念&#xff1a; 什么是哈希冲突hashMap Hash 为什么是16bithashMap 如…

RabbitMQ开启消息跟踪日志(trace)

Trace 是Rabbitmq用于记录每一次发送的消息&#xff0c;方便使用Rabbitmq的开发者调试、排错。 1、启动Tracing插件 在RabbitMQ中默认是关闭的&#xff0c;需手动开启。此处rabbitMQ是使用docker部署的 ## 进入rabbitMq中 docker exec -it rabbitmq1 bash ## 启动日志插件 r…

element el-table树形表格结构,勾选联动 父级勾选,子级全部选中,勾选子级,父级显示勾选状态

需求实现如下 重点使用到 select 以及 select-all 两个方法 返回数据格式 代码实现 <el-table ref"tableRef" :cell-style"{ color: #FFF, background: #333 }":header-cell-style"{ color: #FFF, background: #333 }" row-key"id"…

httprunnet自动化测试实战

引言 自动化测试是指使用软件工具、脚本或编程来执行测试任务&#xff0c;以代替人工执行测试用例的过程。它使用自动化工具和技术来模拟用户操作&#xff0c;验证和评估软件应用程序的功能、性能和稳定性。 自动化测试的主要目的是提高测试效率和质量&#xff0c;它具有以下几…

视频转二维码简单技巧,适用多种视频格式

现在很多商品介绍多是以视频的方式来展现&#xff0c;那么为了方便用户能够同时快速获取视频内容&#xff0c;所以很多的商家现在会将视频生成二维码放到宣传单、展板、海报等宣传内容上&#xff0c;让他人通过扫码获取信息。那么视频二维码生成器的使用方法有哪几个步骤呢&…

矩阵剪辑系统源码----pc/手机端双开发

剪辑系统&#xff0c;剪辑矩阵系统&#xff0c;剪辑矩阵系统主要是针对抖音、快手、bili平台的一个工具&#xff0c;今天就来给大家交流一下这 个产品的主要功能以及构成。剪辑矩阵系统&#xff0c;矩阵剪辑系统源码-这产品主要功能就是一个视频剪辑功能&#xff0c;这个视频剪…