IoC—Inversion of Control,即「控制反轉」,它不是什麼技術,而是一種設計思想。在 Java 開發中, IoC意味着將設計好的對象交給容器控制,而不是傳統的在對象內部直接控制。
傳統Java程序中,咱們直接在對象內部經過new進行建立對象,是程序去主動建立依賴對象;而IoC是有專門的一個容器來建立這些對象,即由IoC容器來控制對象的建立。反轉則是由容器來幫忙建立及注入依賴對象。
IoC不是一種技術,只是一種思想,一個重要的面向對象編程的法則,它能指導咱們如何設計出鬆耦合、更優良的程序。傳統應用程序都是由咱們在類內部主動建立依賴對象,從而致使類與類之間高耦合,難於測試;有了IoC容器後,把建立和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,因此對象與對象之間是鬆散耦合,這樣也方便測試,利於功能複用,更重要的是使得程序的整個體系結構變得很是靈活。java
DI—Dependency Injection,即「依賴注入」:是組件之間依賴關係由容器在運行期決定,形象的說,即由容器動態的將某個依賴關係注入到組件之中。依賴注入的目的並不是爲軟件系統帶來更多功能,而是爲了提高組件重用的頻率,併爲系統搭建一個靈活、可擴展的平臺。經過依賴注入機制,咱們只須要經過簡單的配置,而無需任何代碼就可指定目標須要的資源,完成自身的業務邏輯,而不須要關心具體的資源來自何處,由誰實現。
對於IoC和DI,其實它們是同一個概念的不一樣角度的描述。web
IoC容器就是具備依賴注入功能的容器,IoC容器負責實例化、定位、配置應用程序中的對象及創建這些對象間的依賴。應用程序無需直接在代碼中new相關的對象,應用程序由IoC容器進行組裝。在Spring中BeanFactory是IoC容器的實際表明者。
在 Spring Ioc 容器的表明就是 org.springframework.beans 包中的BeanFactory 接口, BeanFactory 接口提供了 IoC 容器最基本功能;而org.springframework.context 包下的 ApplicationContext 接口擴展了 BeanFactory ,還提供了與Spring AOP 集成、國際化處理、事件傳播及提供不一樣層次的 context 實現 (如針對 web 應用的 WebApplicationContext )。簡單說, BeanFactory 提供了 IoC 容器最基本功能,而 ApplicationContext 則增長了更多支持企業級功能支持。 ApplicationContext 徹底繼承 BeanFactory ,於是 BeanFactory 所具備的語義也適用於 ApplicationContext。spring
Person.java編程
package com.liu5599.test; public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "name: " + name + " age: " + age; } }
Main.javasession
package com.liu5599.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Person p = (Person)context.getBean("person"); System.out.println(p); } }
spring.xmlide
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "person" class = "com.liu5599.test.Person"> <property name="name" value="liuyang" /> <property name="age" value="21" /> </bean> <!--<bean id = "person" class = "com.liu5599.test.Person">--> <!--<property name="name">--> <!--<value>liuyang</value>--> <!--</property>--> <!--<property name="age">--> <!--<value>21</value>--> <!--</property>--> <!--</bean>--> <!--<bean id = "person" class = "com.liu5599.test.Person"--> <!--p:name = "liuyang" p:age = "21">--> </beans>
輸出結果:函數
name: liuyang age: 21
接着講述一個Bean中嵌套着另一個Bean。測試
1.第一種方式是在Student中經過ref屬性引用Person的Bean,可是一旦Person被引用到了Student下,也就不會被其餘的Bean引用了。this
2.第二種方式是在Student的Bean中聲明一個內部的Bean。prototype
3.第三種方式是經過構造函數注入。
將測試類進行修改以下:
package com.liu5599.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Student p = (Student)context.getBean("student"); System.out.println(p); } }
輸出結果:
Student name: liuyang age: 21
在Spring中,支持以下5種類型的做用域:
默認狀況下,做用域是單例。
public class Message { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Message m1 = (Message) context.getBean("message"); m1.setMessage("Message1"); System.out.println("Message1: " + m1.getMessage()); Message m2 = (Message)context.getBean("message"); System.out.println("Message2: " + m2.getMessage()); } }
輸出結果:
Message1: Message1 Message2: Message1
<bean id = "message" class = "com.liu5599.test.Message" scope="prototype" />
運行結果:
Message1: Message1 Message2: null
這裏主要講述List、Set、Map和Properties四種集合類型。
Properties類型相似於特殊的Map,不一樣之處是Map的key能夠爲任意類型對象,而Properties類型的key只能是字符串。
1.首先修改Student類,修改以下。
public class Student { private List<Object> lists; private Set<Object> sets ; private Map<Object, Object> maps ; private Properties pros; public List<Object> getLists() { return lists; } public void setLists(List<Object> lists) { this.lists = lists; } public Set<Object> getSets() { return sets; } public void setSets(Set<Object> sets) { this.sets = sets; } public Map<Object, Object> getMaps() { return maps; } public void setMaps(Map<Object, Object> maps) { this.maps = maps; } public Properties getPros() { return pros; } public void setPros(Properties pros) { this.pros = pros; } private Person person; public Student() {} public Student(Person person) { this.person = person; } public void setPerson(Person person) { this.person = person; } @Override public String toString() { return "Student " + person; } }
2.修改spring.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-3.0.xsd"> <bean id = "person" class = "com.liu5599.test.Person"> <property name = "name" value = "liuyang" /> <property name = "age" value = "21" /> </bean> <bean id = "student" class="com.liu5599.test.Student"> <property name = "lists"> <list> <value>1</value> <ref bean = "person" /> <bean class = "com.liu5599.test.Person"> <property name = "name" value = "abc" /> <property name = "age" value = "20" /> </bean> </list> </property> <property name="sets"> <set> <value>1</value> <ref bean = "person" /> <bean class = "com.liu5599.test.Person"> <property name = "name" value = "abc" /> <property name = "age" value = "20" /> </bean> </set> </property> <property name="maps"> <map> <entry key = "key1" value = "123" /> <entry key = "key2" value-ref = "person" /> <entry key = "key3"> <bean class = "com.liu5599.test.Person"> <property name = "name" value = "abcd" /> <property name = "age" value = "19" /> </bean> </entry> </map> </property> <property name="pros"> <props> <prop key = "name">liuyang</prop> <prop key = "age">21</prop> </props> </property> <property name="person"> <bean class = "com.liu5599.test.Person"> <property name = "name" value = "liuyang" /> <property name = "age" value = "21" /> </bean> </property> </bean> <bean id = "message" class = "com.liu5599.test.Message" scope="prototype" /> </beans>
3.修改測試類,以下。
public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Student s = (Student)context.getBean("student"); System.out.println(s.getLists().toString()); System.out.println(s.getSets().toString()); System.out.println(s.getMaps().toString()); System.out.println(s.getPros().toString()); } }
輸出結果:
[1, name: liuyang age: 21, name: abc age: 20] [1, name: liuyang age: 21, name: abc age: 20] {key1=123, key2=name: liuyang age: 21, key3=name: abcd age: 19} {age=21, name=liuyang}
以上就是Spring Bean的簡單使用方法,可是全都是手動配置的,難以維護,下次我會寫一篇關於註解配置和自動掃描裝配的文章。