Spring IoC 的实现机制

案例一:

Spring 中的 IoC 的实现原理就是工厂模式加反射机制。我们先使用一个简单的案例理解一下:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;// 定义一个水果接口,包含吃的方法
public interface Fruit {// 抽象方法:吃public abstract void eat();
}// 苹果类实现Fruit接口
public class Apple implements Fruit {// 实现eat方法public void eat() {System.out.println("Apple");}
}// 橙子类实现Fruit接口
public class Orange implements Fruit {// 实现eat方法public void eat() {System.out.println("Orange");}
}// 安全工厂类,用于根据类名动态创建Fruit对象
public class SafeFactory {/*** 根据指定的类名创建Fruit对象** @param className 类名,必须是实现了Fruit接口的类的全限定名* @return 创建的Fruit对象,如果出现异常则抛出* @throws ClassNotFoundException 如果找不到指定的类* @throws IllegalAccessException 如果访问类的构造函数时出错* @throws InstantiationException 如果无法实例化类* @throws NoSuchMethodException 如果类没有默认构造函数* @throws InvocationTargetException 如果调用构造函数时出错*/public static Fruit getInstance(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {// 检查类名是否为null或空字符串if (className == null || className.trim().isEmpty()) {throw new IllegalArgumentException("类名不能为空");}// 确保类名符合Java类名的命名规则if (!className.matches("^[a-zA-Z_$][a-zA-Z0-9_$]*$")) {throw new IllegalArgumentException("无效的类名:" + className);}// 加载指定的类,并检查是否实现了Fruit接口Class<?> clazz = Class.forName(className);if (!Fruit.class.isAssignableFrom(clazz)) {throw new IllegalArgumentException("指定的类未实现Fruit接口:" + className);}// 获取类的所有声明的构造函数,确保只有一个公共构造函数Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();if (declaredConstructors.length != 1) {throw new IllegalStateException("指定的类必须有一个默认构造函数:" + className);}// 设置构造函数的访问权限,并实例化对象declaredConstructors[0].setAccessible(true);return (Fruit) declaredConstructors[0].newInstance();}
}// 客户端类,演示如何使用工厂类
public class Client {public static void main(String[] args) {try {// 使用工厂类创建Apple对象Fruit f = SafeFactory.getInstance("Apple"); // 使用全限定类名以确保正确性if (f != null) {f.eat(); // 调用eat方法}} catch (Exception e) {e.printStackTrace();}}
}

        这个简单的案例模拟了Spring IoC的基本原理,但请注意,Spring的实现更为复杂,包括对XML或注解配置的支持、自动扫描、类型安全的依赖注入、AOP支持等。在实际的Spring框架中,这些功能都是通过ApplicationContext来提供的,它可以加载配置,管理Bean的生命周期,以及处理依赖注入。

案例二:

下面我们再写一个Spring IoC的实现机制的步骤,以及一个简单的XML配置文件案例:
1. Bean定义:
        Spring 需要知道如何创建和配置每个对象,这通常是通过XML配置文件完成的,或者通过注解(@Component, @Service, @Repository, @Controller 等)。
2. Bean工厂:
        Spring 使用 BeanFactory 作为基础容器,它负责创建、配置和管理Bean。更高级别的 ApplicationContext 扩展了 BeanFactory,提供了更多功能,如消息源、国际化支持等。
3. 反射:
        Spring 使用Java的反射机制来根据Bean定义创建对象。反射允许在运行时动态创建对象并调用其方法。
4. 依赖注入:
        Spring 通过依赖注入将对象之间的依赖关系解耦。它可以在构造函数、setter方法或属性级别注入依赖。
5. 配置元数据解析:
        Spring 读取XML配置文件或其他元数据源,解析Bean定义并构建Bean的内部表示。
6. 实例化和初始化:
        当需要一个Bean时,Spring容器使用反射创建一个新的实例,然后根据Bean定义注入所有依赖。

以下是一个简单的XML配置文件案例,展示了如何定义和配置Bean:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 定义一个名为myService的Bean --><bean id="myService" class="com.example.MyService"><!-- 使用setter注入依赖 --><property name="myDependency" ref="myDependencyBean"/></bean><!-- 定义一个名为myDependencyBean的Bean --><bean id="myDependencyBean" class="com.example.MyDependency"/></beans>

在这个例子中,MyService 类有一个名为 myDependency 的依赖,它将通过 myDependencyBean Bean注入。Spring 会自动调用 MyService 类中的 setMyDependency 方法来设置这个依赖。

7. 使用Bean:
        在应用程序代码中,你可以通过 ApplicationContext 获取Bean实例,如下所示:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyService myService = (MyService) context.getBean("myService");
myService.doSomething();

这里,ClassPathXmlApplicationContext 从类路径加载配置文件 applicationContext.xml,然后通过 getBean 方法获取 myService Bean 的实例。

通过这种方式,Spring IoC容器管理了对象的生命周期和依赖关系,使得应用程序的组件可以松散耦合。

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

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

相关文章

Vue 3.4.5深度解析:从基础到高级,掌握Composition API与全局API精髓

一、基础函数&特性 1. setup() 函数 作用&#xff1a;setup() 是Vue 3引入的一个新的组件选项&#xff0c;用于定义组件的逻辑。它在组件初始化阶段被调用&#xff0c;替代了Vue 2中的data、methods等选项。特点&#xff1a; 接收props和context作为参数。返回的对象将被…

Spring:jackson-annotaions注解大全

文章目录 一、介绍二、JsonProperty三、JsonIgnore四、JsonInclude五、JsonFormat六、JsonCreator 和 JsonProperty (在构造函数中)七、JsonTypeName 和 JsonTypeInfo八、JsonIgnoreProperties九、JsonSerialize十、JsonDeserialize 一、介绍 jackson-annotations 是 Jackson …

痛心!2岁女童被从17楼推下坠亡,凶手疑是未成年

一起又一起的案件&#xff0c; 如同一部沉重的史诗&#xff0c; 无声地述说着一个共同的真理&#xff1a; 严惩恶魔&#xff0c;实则是在庇护着无数纯真的心灵&#xff0c;守护着更多的孩子。 因为每一起案件的背后&#xff0c;都隐藏着一个个令人心碎的故事。 01 近日&#xf…

错误发生在尝试创建一个基于有限元方法的功能空间时

问题&#xff1a; index cell.index(#直接使用从0开始的索引if0<1ndex<10: #正集流体 subdomains_x[cell,index(] 1 fem1 /usr/bin/python3.8 /home/wy/PycharmProjects/pythonProject2/fem1.pyUnknown ufl object type FiniteElementTraceback (aost recent call last)…

python编程:实现对数据库中图片文件的查看及比对

当谈到图像查看和管理时,我们往往会使用一些工具软件,比如Windows自带的照片查看器或者第三方工具。那如果你想要一个更加强大和定制化的图像查看器呢?这时候就需要自己动手写一个程序了。 C:\pythoncode\new\ShowSqliteImage.py 这里我们将介绍一个使用Python和wxPython编写…

解析Java中1000个常用类:Iterable类,你学会了吗?

在 Java 编程中,集合(Collections)是非常重要的数据结构。无论是数组、列表、集合,还是其他形式的集合,如何高效地遍历这些集合都是一个关键问题。 Java 提供了一个基础接口 Iterable,它为集合类的遍历提供了统一的接口。 本文将深入探讨 Iterable 接口,介绍其用法、实…

FPGA-ARM架构与分类

ARM架构&#xff0c;曾称进阶精简指令集机器&#xff08;Advanced RISC Machine&#xff09;更早称作Acorn RISC Machine&#xff0c;是一个32位精简指令集&#xff08;RISC&#xff09;处理器架构。 主要是根据FPGA zynq-7000的芯片编写的知识思维导图总结,废话不多说自取吧 …

【Python内功心法】:深挖内置函数,释放语言潜能

文章目录 &#x1f680;一、常见内置函数&#x1f308;二、高级内置函数⭐1. enumerate函数&#x1f44a;2. eval函数❤️3. exec函数&#x1f4a5;4. eval与exec 中 globals与locals如何用☔4-1 globals 参数&#x1f3ac;4-2 locals 参数 ❤️5. filter函数&#x1f44a;6. z…

Python 之SQLAlchemy使用详细说明

目录 1、SQLAlchemy 1.1、ORM概述 1.2、SQLAlchemy概述 1.3、SQLAlchemy的组成部分 1.4、SQLAlchemy的使用 1.4.1、安装 1.4.2、创建数据库连接 1.4.3、执行原生SQL语句 1.4.4、映射已存在的表 1.4.5、创建表 1.4.5.1、创建表的两种方式 1、使用 Table 类直接创建表…

16岁适合做什么编程题:探索编程世界的入门之旅

16岁适合做什么编程题&#xff1a;探索编程世界的入门之旅 在数字化浪潮席卷而来的今天&#xff0c;编程已成为一项重要的技能。对于16岁的青少年来说&#xff0c;学习编程不仅可以锻炼逻辑思维&#xff0c;还能为未来的职业发展打下坚实的基础。那么&#xff0c;16岁适合做什…

安卓如何书写注册和登录界面

一、如何跳转一个活动 左边的是本活动名称&#xff0c; 右边的是跳转界面活动名称 Intent intent new Intent(LoginActivity.this, RegisterActivity.class); startActivity(intent); finish(); 二、如果在不同的界面传递参数 //发送消息 SharedPreferences sharedPreferen…

【学习Day4】计算机基础

✍&#x1f3fb;记录学习过程中的输出&#xff0c;坚持每天学习一点点~ ❤️希望能给大家提供帮助~欢迎点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;指点&#x1f64f; ❤️学习和复习的过程是愉快嘚。 1.7.3 流水线 流水线&#xff08;pipeline&#xff09;技术…

单片机按键处理模块

一 介绍 1.key_board用于单片机中的小巧多功能按键支持&#xff0c;软件采用了分层的思想&#xff0c;并且做到了与平台无关&#xff0c;用户只需要提供按键的基本信息和读写io电平的函数即可&#xff0c;非常方便移植&#xff0c;同时支持多个矩阵键盘及多个单io控制键盘。 …

Python 字符串的运算

在 Python 中&#xff0c;字符串支持一系列的运算操作&#xff0c;包括字符串拼接、重复、比较和成员检测等。以下是一些常见的字符串运算&#xff1a; 字符串拼接&#xff1a;使用加号 可以将两个字符串连接起来。例如&#xff0c;"Hello, " "World" 将…

chap5 CNN

卷积神经网络&#xff08;CNN&#xff09; 问题描述&#xff1a; 利用卷积神经网络&#xff0c;实现对MNIST数据集的分类问题 数据集&#xff1a; MNIST数据集包括60000张训练图片和10000张测试图片。图片样本的数量已经足够训练一个很复杂的模型&#xff08;例如 CNN的深层…

商用未来何时来?软银揭示量子计算商业应用现状

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 文丨沛贤/浪味仙 排版丨沛贤 深度好文&#xff1a;3000字丨10分钟阅读 摘要&#xff1a;软银&#xff08;SoftBank&#xff09;先进技术研究所正在积极推进量子计算商业应用&#xff0c;借助与…

如何使用基类指针迭代派生类对象

如果我们想使用基类指针迭代指向的派生类对象&#xff0c;我们需要在基类中声明返回迭代器的虚函数begin和end&#xff0c;然后在派生类中实现begin和end&#xff0c;这样我们就可以使用基类指针指向派生类后使用其迭代器了。 #include<iostream> #include<vector>…

SpringCloud Feign用法

1.在目标应用的启动类上添加开启远程fein调用注解&#xff1a; 2.添加一个feign调用的interface FeignClient("gulimall-coupon") public interface CouponFeignService {PostMapping("/coupon/spubounds/save")R save(RequestBody SpuBondTo spuBounds);…

随记-点选验证码(二)

之前写过一篇文章 随记-点选验证码 &#xff0c;当时借助了 ddddocr 完成了ocr 识别&#xff0c;这篇文章算是对之前的补充。 本次更换了新的方案&#xff1a; 通过 ultralytics&#xff08;YOLO8&#xff09;训练自己的模型 吐槽一句&#xff1a;标注真是一件耗时的事情啊&am…

解锁用户增长密码:订单排队免单+分红

排队分红模式&#xff0c;作为一种创新的营销策略&#xff0c;正逐渐受到实体店家的青睐。这种策略巧妙洞察了消费者的购物心理&#xff0c;成功地将顾客转变为商家的共赢伙伴。 坐标&#xff1a;厦门&#xff0c;我是肖琳 深耕社交新零售行业10年&#xff0c;主要提供新零售系…