Spring IOC與DI核心重點分析
1. Spring 是什么
我們通常所說的 Spring 指的是 Spring Framework(Spring 框架),它是一個開源框架,有著活躍而龐 大的社區(qū),這就是它之所以能長久不衰的原因。Spring 支持廣泛的應(yīng)用場景,它可以讓 Java 企業(yè)級的應(yīng)用程序開發(fā)起來更簡單。
一句話概括 Spring :Spring 是包含了眾多工具方法的 IOC 容器
那么什么是 IOC 呢
2. IOC 是什么
IOC (Inversion of Control 控制反轉(zhuǎn)),就是說 Spring 是一個控制反轉(zhuǎn)的容器
既然提到了控制反轉(zhuǎn),那么就來看看什么是正向控制,什么是反向控制
2.1 正向控制
在我們之前的大部分代碼中,當(dāng)我們要用到一個對象時,我們就需要自己構(gòu)造這個對象,自己 new 對象,自己造,自己用,典型的自給自足生產(chǎn)模式
2.2 反向控制
在 Spring 的大部分代碼中,我們只需要聲明我們需要一個什么樣的對象,對象的構(gòu)造我們不管,這里的對象就是 Spring 幫我們注入進(jìn)來的,對象就來自于 IOC 容器
3. DI 概念說明
說到 IoC 不得不提的一個詞就是“DI”,DI 是 Dependency Injection 的縮寫,翻譯成中文是“依賴注入”的 意思。
所謂依賴注入,就是由 IoC 容器在運行期間,動態(tài)地將某種依賴關(guān)系注入到對象之中。所以,依賴注入 (DI)和控制反轉(zhuǎn)(IoC)是從不同的角度的描述的同一件事情,就是指通過引入 IoC 容器,利用依賴關(guān)系注入的方式,實現(xiàn)對象之間的解耦。
4. Spring 的工作模式可以理解成一個買賣對象的市場
Spring 容器就是這個市場,我們既可以是賣家,也可以是買家
當(dāng)我們是賣家時,將我們的對象注入到 Spring 庫
當(dāng)我們是買家時,聲明我們需要的對象,Spring 從庫中將對象取出來給我們
5. 以一個小程序來理解 IOC 和 DI
當(dāng)我們需要造一輛車時,就需要得到一個四個部分,才能造成一輛車
以代碼實現(xiàn)時,我們就需要這四個對象,先手動將這四個對象注入到庫中
@Component:將被修飾的類注冊到庫中
@Autowired:自動注入,在這里可以理解成從庫中拿到所修飾的元素
這里重寫 toSpring() 只是為了打印對象,沒有其他特殊意義
使用 context.getBeanDefinitionNames() 得到庫中所有對象并打印后,可以清楚的看到,這四個對象已經(jīng)被注入到庫中
后續(xù) car 對象也成功打印
@Component public class Car { @Autowired private Framework framework; @Override public String toString() { return "Car{" + "framework=" + framework + '}'; } }
@Component public class Framework { @Autowired private Bottom bottom; @Override public String toString() { return "Framework{" + "bottom=" + bottom + '}'; } }
@Component public class Bottom { @Autowired private Tire t1; @Autowired private Tire t2; @Autowired private Tire t3; @Autowired private Tire t4; @Override public String toString() { return "Bottom{" + "t1=" + t1 + ", t2=" + t2 + ", t3=" + t3 + ", t4=" + t4 + '}'; } }
@Component public class Tire { @Override public String toString() { return "輪子"; } }
主類
@SpringBootApplication public class IocApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(IocApplication.class, args); Car car = context.getBean(Car.class); // 得到庫中所有的 bean(對象) String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { System.out.println(beanDefinitionName); } System.out.println(car); } }
當(dāng)有一個對象沒有被 @Component 修飾,即庫中沒有這個對象,那么其他對象就不能用@Autowired 得到這個對象,則就會出現(xiàn)以下異常
6. 以 XML 文件的方式將對象注入到我們自己創(chuàng)建的庫中
6.1 新建一個 XML 文件
現(xiàn)在這個 XML 文件就可以看成是一個空的 Spring 庫
<?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/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
6.2 在 Main 中操作這個庫
用 FileSystemXmlApplicationContext() 打開這個 XML 文件之后,就可以在這里對剛剛創(chuàng)建的 Spring 進(jìn)行一些操作
public class Main { public static void main(String[] args) { //1. 以 XML 配置文件手動創(chuàng)建 Spring 容器 FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("spring-config.xml"); // 2. 打印容器中所有對象的 bean-id String[] names = context.getBeanDefinitionNames(); System.out.println("所有對象陳列:"); for (String name : names) { Object bean = context.getBean(name); // 得到此類的全名,即包含包名的名稱 String canonicalName = bean.getClass().getCanonicalName(); System.out.println(name + " " + canonicalName); } int count = context.getBeanDefinitionCount(); System.out.println("一共有" + count + "個"); } }
6.3 XML 文件的方式注入 bean(對象)
以 bean 標(biāo)簽來對對象進(jìn)行注入,以下 XML 用不同的三種方法注入了三個對象
打印后可以清楚的看到,三個對象成功注入
<?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/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- xml的方式注入類,new 的過程也交給 Spring--> <bean id="empty-class" class="com.hsq.ioc2.EmptyClass"/> <!-- 構(gòu)造方法注入類--> <bean id="second-class" class="com.hsq.ioc2.SecondClass"> <!-- 依賴 EmptyClass 注入 SecondClass--> <constructor-arg ref="empty-class"/> </bean> <!-- set 方法注入類--> <bean id="third-class" class="com.hsq.ioc2.ThirdClass"> <property name="EmptyClass" ref="empty-class"/> <property name="SecondClass" ref="second-class"/> </bean> </beans>
public class EmptyClass { public EmptyClass() { System.out.println("被調(diào)用"); } }
public class SecondClass { public SecondClass(EmptyClass emptyClass) { System.out.println("second 被調(diào)用"); } }
public class ThirdClass { public EmptyClass emptyClass; public SecondClass secondClass; public void setEmptyClass(EmptyClass emptyClass) { System.out.println("setEmptyClass() " + emptyClass); this.emptyClass = emptyClass; } public void setSecondClass(SecondClass secondClass) { System.out.println("setSecondClass() " + secondClass); this.secondClass = secondClass; } public ThirdClass() { System.out.println("third 被調(diào)用"); } }
到此這篇關(guān)于Spring IOC與DI核心重點分析的文章就介紹到這了,更多相關(guān)Spring IOC與DI內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java使用common-fileupload實現(xiàn)文件上傳
這篇文章主要為大家詳細(xì)介紹了java使用common-fileupload實現(xiàn)文件上傳的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-10-10Java 日期格式加上指定月數(shù)(一個期限)得到一個新日期的實現(xiàn)代碼
這篇文章主要介紹了Java 日期格式加上指定月數(shù)(一個期限)得到一個新日期的實現(xiàn)代碼,需要的朋友可以參考下2018-05-05