<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>DI on 蛋蛋忧桑</title><link>https://dandansad.com/tags/di/</link><description>Recent content in DI on 蛋蛋忧桑</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Thu, 10 Apr 2025 23:28:34 +0800</lastBuildDate><atom:link href="https://dandansad.com/tags/di/index.xml" rel="self" type="application/rss+xml"/><item><title>IOC? IOC与DI？</title><link>https://dandansad.com/2025/04/10/ioc-ioc%E4%B8%8Edi/</link><pubDate>Thu, 10 Apr 2025 23:28:34 +0800</pubDate><guid>https://dandansad.com/2025/04/10/ioc-ioc%E4%B8%8Edi/</guid><description>&lt;h2 id="-那什么才算-ioc我们重申一次标准"&gt;&lt;a href="#-%e9%82%a3%e4%bb%80%e4%b9%88%e6%89%8d%e7%ae%97-ioc%e6%88%91%e4%bb%ac%e9%87%8d%e7%94%b3%e4%b8%80%e6%ac%a1%e6%a0%87%e5%87%86" class="header-anchor"&gt;&lt;/a&gt;✅ 那什么才算 IoC？我们重申一次标准：
&lt;/h2&gt;&lt;p&gt;真正的控制反转需要满足这三个条件：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;条件&lt;/th&gt;
					&lt;th&gt;是否满足&lt;/th&gt;
					&lt;th&gt;解释&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;你不创建依赖对象&lt;/td&gt;
					&lt;td&gt;✅&lt;/td&gt;
					&lt;td&gt;Kitchen.createFood() or agent.getVehicle() 是“工厂”，你没直接 new&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;你不注入依赖对象&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
					&lt;td&gt;你手动调用 setFood() 或 setVehicle()，控制权仍在你手中&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;容器/外部框架控制依赖注入流程&lt;/td&gt;
					&lt;td&gt;❌&lt;/td&gt;
					&lt;td&gt;没有任何容器帮你自动注入&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="-所以更准确地说"&gt;&lt;a href="#-%e6%89%80%e4%bb%a5%e6%9b%b4%e5%87%86%e7%a1%ae%e5%9c%b0%e8%af%b4" class="header-anchor"&gt;&lt;/a&gt;✅ 所以更准确地说：
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;示例&lt;/th&gt;
					&lt;th&gt;是否 IoC？&lt;/th&gt;
					&lt;th&gt;是否有 IoC 的“倾向/味道”？&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Kitchen.createFood() + setFood()&lt;/td&gt;
					&lt;td&gt;❌ 不是&lt;/td&gt;
					&lt;td&gt;✅ 有工厂感&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;agent.getVehicle() + setVehicle()&lt;/td&gt;
					&lt;td&gt;❌ 不是&lt;/td&gt;
					&lt;td&gt;✅ 有 service locator 的风格&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Spring.getBean(Food.class) 然后自动注入&lt;/td&gt;
					&lt;td&gt;✅ 是&lt;/td&gt;
					&lt;td&gt;✅ 真正的 IoC&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="-一句话解释区别"&gt;&lt;a href="#-%e4%b8%80%e5%8f%a5%e8%af%9d%e8%a7%a3%e9%87%8a%e5%8c%ba%e5%88%ab" class="header-anchor"&gt;&lt;/a&gt;🧠 一句话解释区别：
&lt;/h2&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;IoC 是思想（理念），DI 是具体实现方式之一。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="-来拆解下这两个词"&gt;&lt;a href="#-%e6%9d%a5%e6%8b%86%e8%a7%a3%e4%b8%8b%e8%bf%99%e4%b8%a4%e4%b8%aa%e8%af%8d" class="header-anchor"&gt;&lt;/a&gt;🔍 来拆解下这两个词：
&lt;/h2&gt;&lt;h3 id="-iocinversion-of-control控制反转"&gt;&lt;a href="#-iocinversion-of-control%e6%8e%a7%e5%88%b6%e5%8f%8d%e8%bd%ac" class="header-anchor"&gt;&lt;/a&gt;✅ IoC（Inversion of Control）控制反转：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;是一种 &lt;strong&gt;设计思想&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;目标是：&lt;strong&gt;把控制权从程序员手里“反转”给框架或容器&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不再由你手动控制程序流程和对象组合，而是由框架来“自动调度”&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;你不自己&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，不自己调用&lt;/span&gt; set&lt;span style="color:#960050;background-color:#1e0010"&gt;，框架帮你搞定一切&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="-didependency-injection依赖注入"&gt;&lt;a href="#-didependency-injection%e4%be%9d%e8%b5%96%e6%b3%a8%e5%85%a5" class="header-anchor"&gt;&lt;/a&gt;✅ DI（Dependency Injection）依赖注入：
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;是一种 &lt;strong&gt;实现 IoC 的具体技术手段&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;它的核心是：&lt;strong&gt;将依赖通过某种方式“注入”给目标对象&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;有 3 种常见形式：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;构造器注入&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Setter 注入&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;接口注入&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="-关系总结图"&gt;&lt;a href="#-%e5%85%b3%e7%b3%bb%e6%80%bb%e7%bb%93%e5%9b%be" class="header-anchor"&gt;&lt;/a&gt;✅ 关系总结图：
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;+--------------------+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; Inversion of &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; Control (IoC) &lt;span style="color:#f92672"&gt;|&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;对比项&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; IoC &lt;span style="color:#f92672"&gt;|&lt;/span&gt; DI &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#f92672"&gt;---&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#f92672"&gt;---&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#f92672"&gt;---&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;是什么&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;一种设计思想&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;一种实现方式&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;控制谁&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;控制“对象如何创建和依赖如何组合”的权力从你手中“反转”出去&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;指定“依赖应该怎么注入进来”&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;关系&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;包含关系：&lt;/span&gt;DI &lt;span style="color:#960050;background-color:#1e0010"&gt;是&lt;/span&gt; IoC &lt;span style="color:#960050;background-color:#1e0010"&gt;的一种实现手段&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;属于&lt;/span&gt; IoC &lt;span style="color:#960050;background-color:#1e0010"&gt;的一种实践方式&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;举例&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; Spring &lt;span style="color:#960050;background-color:#1e0010"&gt;框架控制&lt;/span&gt; Bean &lt;span style="color:#960050;background-color:#1e0010"&gt;生命周期&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;Autowired &lt;span style="color:#960050;background-color:#1e0010"&gt;注入依赖&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## ✅ 什么是 Service Locator？
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;### **Service Locator** 是一种 **设计模式**，其核心目的是：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;提供一个全局的服务查找器&lt;/span&gt;&lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，通过它你可以在任何地方查找、获取到需要的服务或依赖对象，而不需要手动创建和管理。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;换句话说，&lt;/span&gt;&lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;它是一个中介&lt;/span&gt;&lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，负责管理对象的创建和查找。你只需要请求它来获取服务，而不用关心服务怎么创建或者存在哪儿。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;### 🧠 核心思想：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;从服务定位器（&lt;/span&gt;Service Locator&lt;span style="color:#960050;background-color:#1e0010"&gt;）中获取服务，而不是自己直接管理和创建对象。&lt;/span&gt;&lt;span style="color:#f92672"&gt;**&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;### 🚨 但是，这种方式的问题：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;虽然&lt;/span&gt; Service Locator &lt;span style="color:#960050;background-color:#1e0010"&gt;提供了“获取依赖”的能力，但它有一个隐含的缺点：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;它破坏了“依赖显式化”的原则&lt;/span&gt;&lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，也就是，&lt;/span&gt;&lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;你没有直接看出对象的依赖是什么&lt;/span&gt;&lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，导致了代码的可维护性差，特别是当系统变得复杂时。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;### 这和 DI 的区别：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#f92672"&gt;**&lt;/span&gt;DI&lt;span style="color:#f92672"&gt;**&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;明确地告诉你：你需要哪些依赖，并且这些依赖会通过某种方式（构造器、&lt;/span&gt;setter &lt;span style="color:#960050;background-color:#1e0010"&gt;等）注入给你。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#f92672"&gt;**&lt;/span&gt;Service Locator&lt;span style="color:#f92672"&gt;**&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;则是通过一个全局对象来管理和查找依赖，你在使用时不关心这些依赖怎么被创建的。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## ✅ 举个简单的例子：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;### 1️⃣ 没有 Service Locator（直接依赖注入）：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;```&lt;/span&gt;java
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Restaurant&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; Food food;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Restaurant&lt;/span&gt;(Food food) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.food &lt;span style="color:#f92672"&gt;=&lt;/span&gt; food;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;order&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; food.eat();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通过构造器注入 &lt;code&gt;Food&lt;/code&gt;，明确表达了 &lt;code&gt;Restaurant&lt;/code&gt; 依赖于 &lt;code&gt;Food&lt;/code&gt;。当你创建 &lt;code&gt;Restaurant&lt;/code&gt; 时，&lt;strong&gt;需要显式地提供 &lt;code&gt;Food&lt;/code&gt;&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="2-使用-service-locator"&gt;&lt;a href="#2-%e4%bd%bf%e7%94%a8-service-locator" class="header-anchor"&gt;&lt;/a&gt;2️⃣ 使用 Service Locator：
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Restaurant&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Food food;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;order&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 通过 Service Locator 获取 food&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; food &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ServiceLocator.&lt;span style="color:#a6e22e"&gt;getService&lt;/span&gt;(Food.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; food.&lt;span style="color:#a6e22e"&gt;eat&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在这个例子里，&lt;code&gt;Restaurant&lt;/code&gt; 并不直接关心 &lt;code&gt;Food&lt;/code&gt; 是怎么被创建的，它只是通过 &lt;code&gt;ServiceLocator.getService(Food.class)&lt;/code&gt; 去查询获取 &lt;code&gt;Food&lt;/code&gt;。
你不用显式地提供 &lt;code&gt;Food&lt;/code&gt;，而是让 &lt;code&gt;Service Locator&lt;/code&gt; 去处理。&lt;/p&gt;
&lt;h3 id="service-locator-类的简单实现"&gt;&lt;a href="#service-locator-%e7%b1%bb%e7%9a%84%e7%ae%80%e5%8d%95%e5%ae%9e%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;Service Locator 类的简单实现：
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ServiceLocator&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; Map, Object&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; services &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 注册服务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;registerService&lt;/span&gt;(Class serviceClass, T serviceInstance) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; services.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(serviceClass, serviceInstance);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 获取服务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; T &lt;span style="color:#a6e22e"&gt;getService&lt;/span&gt;(Class serviceClass) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (T) services.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(serviceClass);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在这段代码中，&lt;code&gt;ServiceLocator&lt;/code&gt; 提供了一个静态方法来获取所有注册过的服务对象，而你不需要关心这些对象是怎么创建的。&lt;/p&gt;</description></item><item><title>IOC-Exercise</title><link>https://dandansad.com/2025/03/18/ioc-exercise/</link><pubDate>Tue, 18 Mar 2025 13:31:24 +0800</pubDate><guid>https://dandansad.com/2025/03/18/ioc-exercise/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;严格地说，这个不算IOC，详见：&lt;a class="link" href="https://dandansad.com/2025/04/10/ioc-ioc%e4%b8%8edi%ef%bc%9f/" target="_blank" rel="noopener"
 &gt;IOC? IOC与DI？&lt;/a&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;一个IOC（控制反转）和DI（依赖注入）的练习程序，实际上和&lt;a class="link" href="https://dandansad.com/2025/03/11/highway-toll-framework/" target="_blank" rel="noopener"
 &gt;Highway-Toll-Framework&lt;/a&gt;的实现基本类似。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;\&lt;/span&gt;&lt;span style="color:#f92672"&gt;---&lt;/span&gt;IOC&lt;span style="color:#f92672"&gt;-&lt;/span&gt;Exercise
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Agent.java
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Person.java
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Vehicle.java
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; VehicleType.java
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="agentjava"&gt;&lt;a href="#agentjava" class="header-anchor"&gt;&lt;/a&gt;Agent.java
&lt;/h2&gt;&lt;p&gt;提供findVehicleClasses方法，扫描包中的类，返回class列表。提供getVehicle方法，创建所给名称对应的车辆类，返回相应实例。&lt;/p&gt;
&lt;h2 id="personjava"&gt;&lt;a href="#personjava" class="header-anchor"&gt;&lt;/a&gt;Person.java
&lt;/h2&gt;&lt;p&gt;这个程序的主类，在里面通过Agent类来获取所需的具体对象，在通过setVehicle方法注入到Person类中，从而调用不同类的同名方法。&lt;/p&gt;
&lt;h2 id="vehiclejava"&gt;&lt;a href="#vehiclejava" class="header-anchor"&gt;&lt;/a&gt;Vehicle.java
&lt;/h2&gt;&lt;p&gt;接口，所有车辆类实现该接口，再在车辆类上打注解便可以不侵入原有代码增加新类。&lt;/p&gt;
&lt;h2 id="vehicletypejava"&gt;&lt;a href="#vehicletypejava" class="header-anchor"&gt;&lt;/a&gt;VehicleType.java
&lt;/h2&gt;&lt;p&gt;注解类，存储了类的名称值，一个类对应多个名称。&lt;/p&gt;</description></item></channel></rss>