一 IOC和 Bean介紹
IOC也被稱爲DI。使用構造器參數,fatory參數,屬性的方式的設置對象實例。在這個過程當中建立bean的時候,容器會注入這些依賴,Bean自己經過使用類的直接構造來控制其依賴項的實例化或位置的過程,由於建立Bean的方式完成是反過來的,因此稱爲Inversion of Control (IoC)。說句人話就是之前建立對象是經過new,如今不new了,直接經過類的構造注入對象。html
org.springframework.beans
和 org.springframework.context
是 IOC 容器的核心。BeanFactory 接口提供了高級的配置對象的能力;ApplicationContext 是 BeanFactory 的子接口,其額外的功能有AOP特點,消息和資源處理,事件傳播等功能,其徹底可以取代BeanFactory,就像父親是貧農,兒子是高富帥 ;具體的容器好比WebApplicationContext提供了豐富的web 應用功能。java
在spring中,對象是應用的骨架,其被IOC container 所管理,也能夠稱爲 Bean;bean的實例化,組裝,和其生命週期都是由 IOC container 管理。Bean和其相互的依賴都是在 配置元數據( configuration metadata)中 配置,而後被IOC容器所管理使用。web
二 container 總覽
org.springframework.context.ApplicationContext
其實 表明的就是 IOC container ,它負責 Bean的實例化,組裝,和配置。IOC 容器是如何 配置和管理Bean呢?其經過 配置元數據( configuration metadata)的方式得到指示來管理Bean。那麼 什麼是配置元數據( configuration metadata)呢?configuration metadata 其實就是 XML , java 註解,和java代碼。spring
經過少許的配置ApplicationContext就能夠開箱即用spring,一般一個單獨的應用是會建立ClassPathXmlApplicationContext 或者 FileSystemXmlApplicationContext 實例。儘管 xml 是 一種傳統的配置元數據的格式,可是你也可使用少許的xml顯示聲明的支持java註解和或者Java代碼這種元數據格式。在許多應用場景中會建立不少個IOC container 而不是一個。bash
當你的對象和配置元數據完成以後,ApplicationContext 會初始化和建立,而後你就能夠徹底執行系統或者應用,以下圖: markdown

三 初識配置元數據
spring 的 配置 最少須要一個或者多個bean,基於xml的配置 <bean>
須要在頂級元素 <beans>
內部,對應的基於java 配置就是 @Bean(用於方法上面) 註解 和 @Configuration(用於類上面)註解。在 <bean>
中 id 表示 bean的惟一標識,class表示bean的全類名,示例以下:app
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
複製代碼
四 實例化container
提供給ApplicationContext一個或者多個字符串形式的資源路徑,ApplicationContext就會經過這個資源路徑去加載這些外部 configuration metadata。ui
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
複製代碼
在 <property>
的屬性中 name 元素 表示 javaBean的屬性,ref指向其它bean的定義。this
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- services -->
<bean id="iocService" class="com.youku1327.ioc.service.IocService">
<property name="iocDao" ref="iocDao"/>
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for services go here -->
</beans>
複製代碼
五 組裝xml
在實際開發中業務層和邏輯層是分開的,也就是說一個xml配置bean耦合度過高,咱們須要解耦就須要定義多個mxl,可是,如何在一個xml中引用另外一個xml中的bean呢? 咱們可=能夠經過<import/>
元素加載來自其餘xml中的bean。在引入外部的xml時,都是當前xml的相對路徑,以下示例:services.xml在當前xml同級目錄,message.xml在當前xml目錄的子目錄。spa
<beans>
<import resource="services.xml"/>
<import resource="resources/message.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>
複製代碼
六使用container
ApplicationContext 是一個高級factory維持着不一樣的bean和依賴關係註冊表。使用 這個接口的T getBean(String name, Class requiredType) 方法就能得到bean的實例。
6.1 pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
</dependencies>
複製代碼
6.2 dao
/**
* @Author lsc
* @Description <p>ioc dao </p>
* @Date 2019/10/29 20:04
*/
public class IocDao {
}
複製代碼
6.3 service
/**
* @Author lsc
* @Description <p> </p>
* @Date 2019/10/29 20:03
*/
public class IocService {
private IocDao iocDao;
private String name;
public IocDao getIocDao() {
return iocDao;
}
public void setIocDao(IocDao iocDao) {
this.iocDao = iocDao;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
複製代碼
6.4 dao.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- services -->
<bean id="iocDao" class="com.youku1327.ioc.dao.IocDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for services go here -->
</beans>
複製代碼
6.5 services.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="dao.xml"/>
<!-- services -->
<bean id="iocService" class="com.youku1327.ioc.service.IocService">
<property name="iocDao" ref="iocDao"/>
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for services go here -->
</beans>
複製代碼
6.6 application
/**
* @Author lsc
* @Description <p> 初始ioc</p>
* @Date 2019/10/29 22:22
*/
public class Application {
public static void main(String[] args) {
// 建立和配置 beans
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"services.xml", "dao.xml"});
// 得到配置的實例
IocService service = context.getBean("iocService", IocService.class);
// 使用配置的實例
service.setName("youku1327");
System.out.println(service.getName());
}
}
複製代碼
6.7 輸出結果

七參考文檔和公衆號
源碼在公衆號對應文章末尾。

本文同步分享在 博客「知識追尋者」(JueJin)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。