首先我們需要了解一下是什麼是Ioc。
Ioc是Spring的核心技術之一,全稱是Inversion of Control(控制反轉)。最原始的創建對象的方法就是通過new來實現(手動的編寫代碼實現):
new Hollow();
而Spring提供了Ioc容器用於對象的創建以及配置、管理、銷燬等。
控制:容器進行組件代碼的控制和管理
反轉:組件代碼的控制權由外部代碼轉移到了內部容器 (程序員到容器)
當應用了IoC,一個對象依賴的其它對象會通過被動的方式傳遞進來,而不是這個對象自己創建或者查找依賴對象,這樣做降低了類之間的耦合程度。不是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。
那麼到底什麼是容器?
從程序的角度,容器實際上就是某些特定接口的實現類的實例。
Spring提供了兩種不同的類型的容器:
Spring BeanFactory容器: 最簡單的容器,給依賴注入提供了基本的支持
ApplicationContext容器: ApplicationContext 容器繼承自BeanFactory,它包括 BeanFactory 容器的所有功能,並對其功能進行了擴展。
Spring BeanFactory 容器
org.springframework.beans.factory.BeanFactor 接口
BeanFacotry是spring中比較原始的Factory。如XMLBeanFactory就是一種典型的BeanFactory。原始的BeanFactory無法支持spring的許多插件,如AOP功能、Web應用等。
ApplicationContext接口,它由BeanFactory接口派生而來,ApplicationContext包含BeanFactory的所有功能,通常建議比BeanFactory優先。
代碼:
public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String var1) throws BeansException; <T> T getBean(String var1, Class<T> var2) throws BeansException; Object getBean(String var1, Object... var2) throws BeansException; <T> T getBean(Class<T> var1) throws BeansException; <T> T getBean(Class<T> var1, Object... var2) throws BeansException; <T> ObjectProvider<T> getBeanProvider(Class<T> var1); <T> ObjectProvider<T> getBeanProvider(ResolvableType var1); boolean containsBean(String var1); boolean isSingleton(String var1) throws NoSuchBeanDefinitionException; boolean isPrototype(String var1) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException; @Nullable Class<?> getType(String var1) throws NoSuchBeanDefinitionException; String[] getAliases(String var1); }
getBean方法:從容器中獲取Bean對象
is方法:單例,原型,bean類型的判斷
get方法:獲取Bean類型和別名
ApplicationContext 的主要實現類
ClassPathXmlApplicationContext:從 類路徑下加載配置文件
FileSystemXmlApplicationContext: 從文件系統中加載配置文件
ConfigurableApplicationContext: 擴展於 ApplicationContext,新增加兩個主要方法:refresh() 和 close(), 讓 ApplicationContext 具有啓動、刷新和關閉上下文的能力
ApplicationContext :在初始化上下文時就實例化所有單例的 Bean。
WebApplicationContext: 是專門爲 WEB 應用而準備的,它允許從相對於 WEB 根目錄的路徑中完成初始化工作
Bean註冊到Ioc容器過程
1、Bean配置信息(xml配置文件、配置類、註解)定義了Bean的實現及依賴關係,即Bean的配置信息
2、Spring容器根據各種形式的Bean配置信息在容器內部建立Bean定義註冊表
3、容器根據註冊表加載、實例化Bean,並建立Bean和Bean的依賴關係,最後將這些準備就緒的Bean放到Bean緩存池中,以供外層的應用程序進行調用
Bean註冊方式
一、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"> <bean id="hollow" class="com.example.bean_configuration.Hollow"></bean> </beans>
配置文件位置、名稱不固定,建議命名爲applicationContext.xml
id:創建的對象名稱
class:需要進行註冊的Bean全路徑
使用靜態工廠創建和使用實例工廠創建與使用類的無參構造函數相似,不再介紹
測試方法
public void classBeanConfiguration() { ApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/applicationContext.xml"); System.out.println("從容器獲取Bean"+applicationContext.getBean("hollow")); }
二、java配置類
配置類
@Configuration public class SpringConfiguration { @Bean public HollowController hollowController(){ return new HollowController(); } }
測試類
@Test public void xmlBeanConfiguration1() { ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfiguration.class); System.out.println("從容器獲取Bean: "+applicationContext.getBean("hollowController")); }
三、註解
添加註解
@Controller public class AnnotationController { public AnnotationController() { System.out.println("annotationController創建了"); } }
開啓掃描
@ComponentScan(value="com.example.bean_configuration.configuration.controller") @Configuration public class SpringConfiguration { }
或者
<context:component-scan base-package="com.example.bean_configuration.configuration.controller" ></context:component-scan>
測試方法
@Test public void xmlBeanConfiguration1() { ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfiguration.class); System.out.println("從容器獲取Bean: "+applicationContext.getBean("annotationController")); }
注意:@Controller註解僅僅其標記作用,開啓註解掃描@ComponentScan後纔會註冊Bean