Spring中用文言文故事理解IOC以及DI

2023-10-15 13:30

本文主要是介绍Spring中用文言文故事理解IOC以及DI,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

其貌如水而魂似酒,闻而知其性,饮而呛其喉,久而觉其醇。

Spring这东西,第一次听,觉得好像是那么一回事儿;第二次听,觉得好像又不是那么一会回事;听多了,觉得更加面目全非甚至越来越抽象了;直到以后用的多了,来来回回的套路都拆清了,却愈发的觉得其与最开始被叨叨叨描述的庞大与威严景貌相去甚远,才开始逐渐意识到,也许先前的无法解读,可能就是因过度解读所产生的罪孽。




这仿佛是一个变形版的“恐怖谷效应”,也就是说:

  • 一个物,你对他不做任何解读,那它就是一个物,没有争议;
  • 一个物,你对它稍作解读,你开始觉得平凡之物却有神来之笔,寻常之语恰有磅礴之势,物的价值被升华,但这种升华也会造成对其原有形态的撕裂,但因其程度甚微,物还是物
  • 一个物,你对它过度解读,试图把一个物推向一个非物的“王座”,却因为物的固有特性使其永远在无限逼近非物的层次却又不得不永恒的退却在非物的层次之外,撕裂了自己原来的形态却无法进阶成新的形态,这种认知的失衡导致了物亦非物的感觉产生。

在这里插入图片描述


因此,回归正题,个人觉得自己以前也是在通过一些标准化,形象化的解释,试图将机器层面的IOC推向生活层面来尝试理解,但这明显是一种困难的事情,或者说是一件不轻松的事情,因为这个入口开在了一个我不了解的地方,从一个我不了解的ioc开始走到一个我了解的地方,那既然我一开始就不了解,那还怎么走?那不如我们反过来,从一个我们了解的地方反向触摸到一个我们不了解的层次,但又不过分神化,这样也许能帮助我们更好的理解。


故事一:
江边垂钓一老叟,久而无鱼,然自岿然不动,抛竿收竿,钩下无鱼,遂配竿挂饵,挂毕复抛,时近晌午,方得一鱼,收竿而归。归毕,家中小儿出,视之曰:“鱼近肥,吾不食。”叟听罢,认道而返,归鱼入江,起竿而垂,久毕,复得一鱼,收笼而归。归毕,家中小儿出,视之曰:“鱼过羸,吾不食”。叟无奈,携鱼返,抛鱼归故,起竿而垂,骄阳歇力,指西而往,叟终得鱼,收竿归宿,岸风已冷,遂快行。家中小儿饥,故不辩鱼之增减,叟得以腌之,烹之,共食之。


故事二:
江边垂钓一老叟,久而无鱼,遂折竿而弃之,怒曰:“天道无鱼而人道有羹,吾独受此殃人之辘辘呼?” 老叟归,问小儿之所好,儿偏认三尺四寸之鱼,叟听罢拍案挥金,白银灿灿,靓若美人,小儿得金出,至酒栈,抛银两一二,点三尺四寸五香之鱼着六叶香芹浇七勺盐八勺醋拉九处花刀十分清熟。少卿,小儿携鱼归,与老叟品,呼民之乐





解析: 首先,故事一和故事二都是吃鱼,但方式却是截然不同的。在故事一中,老人(程序猿)贯穿了钓鱼,得鱼,烹鱼的始终,而这是一种十分辛苦(高耦合)的工作,假如说在做完之后,小儿(客户)的需求变了,那老人就得重新回去钓鱼,如果小儿(客户)要吃清蒸巨王乌贼(MySql),老人就得回去钓巨王乌贼(new 巨王乌贼的对象),如果小儿(客户)改口味要喝紫皮泥鳅汤(sqlserver),那老人就得回去钓紫皮泥鳅(new紫皮泥鳅的对象),且因为工作复杂度太高,如果老人钓来了鱼但不会烹饪把鱼弄糊了,那这个巨大的影响会导致一切前功尽弃,且因为前面准备的工作过于复杂,老人再准备钓鱼的时候肯定也会头皮发麻。

所以有了故事二,老人(程序猿)问小儿(客户)想吃什么,于是给钱(写好接口),小儿拿钱去买吃食,把钱交给了酒店(顺着接口唤醒了spring),于是酒店(spring)拿钱办事,知道了对方想吃什么鱼(对象),做好之后就把鱼交给了对方,至于怎么做鱼那就是厨子(mapper)的事情了,如此一来工作效率大大提高,执行过程也被大幅度降低难度(解耦),从而让小儿(客户)吃上了鱼,无论他的需求有多么善变。



因此,鱼还是那条鱼,鱼(对象)没有消失,但鱼被操作(对象被new)的权利,已经从老叟(程序猿)的手中被反转到了酒店(spring)的手中,这个操作就叫做IOC(控制反转)。


至于DI(依赖注入),就是拿钱吃鱼,人想要获取热量不再饿肚子,就要依赖鱼所提供的蛋白质营养,而在人挨饿(程序运行)的过程中,Spring悄悄的把鱼拿给(注入给)了客户,用户得以饱食,这个过程叫依赖注入。
这里不好理解是以为“注入”这个词是面向于程序角度来提出的,注入吗,联想就是打针注射,药液混合着血液在人体内流淌,这个流淌本身就是程序运行本身,在血液流淌的时候药液被突然注射了进来,在程序运行的时候对象突然被Spring拿了进来,这个时候用注入就比较合适了。

举个例子:下图左右两个状态,程序嘛,是死的,你给它输入个1,让它运行1+1,那结果就会是2,也就是一个【输入】对应一个【输出】,这个状态是垂直分布的,所以左图的结果就是吃不到。
而右边图,一个死程序垂直跑,中途突然被一个叫Spring的硬塞了一条鱼,程序吃饱了,从而改变了自己曾观测到并认为能够抵达的未来,为了描述这种命运被转变的神秘魅力,以及被改变命运者在一霎间的震惊与迷惑,所以使用了“注入”一词。

在这里插入图片描述

那么接下来我们从一个IDEA例子来理解一下第二种方式的“吃鱼”:

  1. 第一步,想要从酒店买鱼,买虽然方便,但酒店是自己盖的,先开启挖地基。地基就是一个最最普通的Maven项目即可。在这里插入图片描述
  2. 包名和类名之类的就不再演示了,建立好之后我们把这个项目作为父项目,因此删除原来项目带有的src目录,然后在pom.xml导入相应的坐标,取得营销执照。
 		<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.5.RELEASE</version></dependency>

在这里插入图片描述

  1. 然后在父项目下建立子模块,在原来的项目上右键建立一个module在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  1. 然后建立对应的包结构,在src/main/java/对应包/pojo层建立一个实体类,实体类生成对应的getset方法,只需要一个字段演示就好,这个对象就是鱼的供应商。在这里插入图片描述
  2. 然后在resources文件夹下beans.xml,当然名字无所谓,将配置信息拷贝进去。这里的bean标签内容是自定义的,id就是随便的一个名字,class是对应的实体类位置,property参数用来指定对应的字段或对象,name是对象或实体类中的字段名,value是赋值。
<?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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--使用spring来创建对象--><bean id="hello" class="com.spring.pojo.Hello"><!--property中value引用的是具体的值,ref参数是应用spring容器中创建好的对象--><property name="str" value="spring"/></bean></beans>

6.写一个测试类

 public class MyTest {public static void main(String[] args) {//获取上下文,获取Spring容器ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");//对象并没有被直接new,而是从spring容器中取,getBean()中填写的是在xml中注册的bean名Hello hello = (Hello) context.getBean("hello");System.out.println(hello);}
}

在这里插入图片描述
输出,发现我们没有new任何关于Hello的对象,但依然出现了结果。在这里插入图片描述
所以,虽然我们没有去new对象,但对象并没有消失而是被Spring建立了,而作为创建对象的主角由程序员反转给了Spring,这就是IOC的实现,而依赖注入是IOC实现的方式。

这篇关于Spring中用文言文故事理解IOC以及DI的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/218037

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听