參考文章:http://www.iteye.com/blogs/subjects/sPRing3?page=3
IOC:控制反轉1.將設計好的對象交給容器控制,而不是傳統的在你對象內部直接控制,創建和查找依賴對象的控制權交給容器2.不是一種技術,是一種思想,松耦合,方便進行測試DI:依賴注入 DI與IOC:1.IOC具有依賴注入功能的容器,容器動態的將某個依賴關系注入到組件之中,并非帶來更多的功能,提升重用的頻率2.同一個概念不一樣角度的描述,控制反轉控制對象一個層面,很難想到誰來維護對象的關系。依賴注入,明確描述了被注入對象依賴IOC容器配置依賴對象●誰依賴于誰:當然是應用程序依賴于IoC容器;●為什么需要依賴:應用程序需要IoC容器來提供對象需要的外部資源;●誰注入誰:很明顯是IoC容器注入應用程序某個對象,應用程序依賴的對象;●注入了什么:就是注入某個對象所需要的外部資源(包括對象、資源、常量數據)。
基本環境:
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.samlai.spring</groupId> <artifactId>spring</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.1.5.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <!-- Junit測試類 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies></project>1.hello world例子:
接口:
package spring.Tinterface;public interface HelloImp { public void hello();}實現類:package spring.realize;import spring.Tinterface.HelloImp;public class HelloRealize implements HelloImp{ public void hello() { System.out.println("Hello World!"); }}測試類:/** * applicationContext實例化對象 */ @Test public void ApContextTestHello(){ //讀取配置文件實例化一個IOC容器 ApplicationContext context=new ClassPathXmlApplicationContext("hello.xml"); //從容器中獲取對應的bean,注意此處"面向接口編程,而不是面向實現" HelloImp helloImp=context.getBean("hello",HelloImp.class); //執行業務邏輯 helloImp.hello(); System.out.println("ApplicationContext"); }BeanFactory:提供了IOC容器最基本的功能,可以從classpath或文件系統等獲取資源而ApplicationContext則增加更多企業級功能支持,ApplicationContex完全繼承BeanFactory
/** * BeanFactory實例化對象 */ @Test public void BeanFactoryTestHello(){ //1.ClassPathResource方式// Resource resource=new ClassPathResource("hello.xml"); //2.FileSystemResource方式 File file=new File("resource/hello.xml"); Resource resource=new FileSystemResource(file); BeanFactory beanFactory=new XmlBeanFactory(resource); //從容器中獲取對應的bean,注意此處"面向接口編程,而不是面向實現" HelloImp helloImp=beanFactory.getBean("hello",HelloImp.class); //執行業務邏輯 helloImp.hello(); System.out.println("BeanFactory"); }2.Bean說明
Bean的配置:IOC目的:管理bean,這些Bean將根據配置文件進行創建,而Bean定義在容器內部由BeanDefinition對象表示,該定義要包含以下信息:●全限定類名(FQN):用于定義Bean的實現類;●Bean行為定義:這些定義了Bean在容器中的行為;包括作用域(單例、原型創建)、是否惰性初始化及生命周期等;●Bean創建方式定義:說明是通過構造器還是工廠方法創建Bean;●Bean之間關系定義:即對其他bean的引用,也就是依賴關系定義,這些引用bean也可以稱之為同事bean 或依賴bean,也就是依賴注入。Bean定義只有“全限定類名”在當使用構造器或靜態工廠方法進行實例化bean時是必須的,其他都是可選的定義。難道Spring只能通過配置方式來創建Bean嗎?回答當然不是,某些SingletonBeanRegistry接口實現類實現也允許將那些非BeanFactory創建的、已有的用戶對象注冊到容器中,這些對象必須是共享的,比如使用DefaultListableBeanFactory 的registerSingleton() 方法。不過建議采用元數據定義。Bean的命名:每個Bean可以有一個或多個id(或稱之為標識符或名字),在這里我們把第一個id稱為“標識符”,其余id叫做“別名”;這些id在IoC容器中必須唯一。指定id和name,id就是標識符,而name就是別名,必須在Ioc容器中唯一使用<alias>標簽指定別名,別名也必須在IoC容器中唯一實例化Bean:1.默認空構造器,<bean id="xxx" class="xxx">2.有參數構造器:在bean內配置+<constructor-arg>3.使用靜態工廠方式實例化Bean,使用這種方式除了指定必須的class屬性,還要指定factory-method屬性來實例化Bean的方法,而且靜態工廠方法也允許方法參數 Spring Ioc將調用此屬性指定的方法來獲取Bean 4.使用實例化方法實例化Bean,使用這種方式不能指定class屬性,此時必須使用factory-bean屬性來指定bean,factory屬性指定實例化Bean方式,而且使用實例工廠 允許指定方法參數,方式和使用構造器方式一樣
xml配置:
<!-- id是唯一標示符,其他id叫做別名 --> <bean id="helloOne" name="helloOne" class="spring.realize.HelloRealize"></bean> <!-- 構造器的配置文件 --> <!--使用默認構造參數--> <bean id="helloC1" class="spring.realize.HelloConstructorRealize"></bean> <!-- 指定構造器參數 --> <bean id="helloC2" class="spring.realize.HelloConstructorRealize"> <constructor-arg index="0" value="Hello Spring!"/> </bean> <!-- 使用靜態工廠配置 --> <bean id="factoryHello" class="spring.realize.HelloFactory" factory-method="newIntance"> <constructor-arg index="0" value="Bean Factory Spring..." /> </bean> <!-- 實例化工廠bean創建bean --> <!-- 1.定義實例工廠Bean --> <bean id="beanInstanceFactoryHello" class="spring.realize.HelloInstanceFactory"></bean> <!-- 2.使用實例工廠Bean創建Bean --> <bean id="instanceBean" factory-bean="beanInstanceFactoryHello" factory-method="newInstance"> <constructor-arg index="0" value="Instance Spring!"></constructor-arg> </bean>實現類:
package spring.realize;import spring.Tinterface.HelloImp;public class HelloConstructorRealize implements HelloImp{ private String message; public HelloConstructorRealize(){ this.message="this is constructor Test."; } public HelloConstructorRealize(String message) { this.message = message; } public void hello() { System.out.println(this.message); } }package spring.realize;import spring.Tinterface.HelloImp;public class HelloFactory { //靜態工廠的方法 public static HelloImp newIntance(String message){ return new HelloConstructorRealize(message); }}package spring.realize;import spring.Tinterface.HelloImp;//實例化工廠public class HelloInstanceFactory { public HelloImp newInstance(String message){ return new HelloConstructorRealize(message); }}測試類:/** * id與name進行對比 */ @Test public void IdAndNameTest(){ ApplicationContext context=new ClassPathXmlApplicationContext("hello.xml"); HelloImp helloImp=context.getBean("helloOne",HelloImp.class); helloImp.hello(); String[] alias=context.getAliases("helloOne"); //alias.length = 0 //因此別名不能和id一樣,如果一樣則由IOC容器負責消除沖突 System.out.println("alias.length = "+alias.length); Assert.assertEquals(0, alias.length); System.out.println("IdAndNameTest"); } /** * constructor構造器的建立 */ @Test public void ConstrouctTest(){ ApplicationContext context=new ClassPathXmlApplicationContext("hello.xml"); HelloImp h1=context.getBean("helloC1",HelloImp.class); HelloImp h2=context.getBean("helloC2",HelloImp.class); h1.hello(); h2.hello(); /* * 打印結果: * this is constructor Test. Hello Spring! */ System.out.println("ConstrouctTest"); } /** * 靜態工廠Factory的測試 * */ @Test public void FactoryTest(){ ApplicationContext context=new ClassPathXmlApplicationContext("hello.xml"); HelloImp factoryBean=context.getBean("factoryHello",HelloImp.class); factoryBean.hello(); //打印:Bean Factory Spring... System.out.println("FactoryTest"); } /** * 實例化Factory的測試 * */ @Test public void instanceFactoryTest(){ ApplicationContext context=new ClassPathXmlApplicationContext("hello.xml"); HelloImp factoryBean=context.getBean("instanceBean",HelloImp.class); factoryBean.hello(); //打印:Instance Spring! System.out.println("instanceFactoryTest"); }
新聞熱點
疑難解答