SpringIOC的概念理解、構造器註入、setter註入、p命名空間註入、IOC容器介紹與比較
1、IOC概念理解
IOC(Inversion of Control)即“控制反轉”,不是什麽技術,而是一種設計思想。在Java開發中,Ioc意味著將你設計好的對象交給容器控制,而不是傳統的在你的對象內部直接控制,IOC容器負責實例化、定位、配置應用程序中的對象及建立這些對象間的依賴,由spring來負責控制對象的生命周期和對象間的關系。
DI(Dependency Injection)即“依賴註入”:由容器動態的將某個依賴關系註入到組件之中。依賴註入的目的並非為軟件系統帶來更多功能,而是為了提升組件重用的頻率,並為系統搭建一個靈活、可擴展的平臺。
例如:你將需要尋找的理想中的對象(胸大、屁股大、年輕、有文化)交給婚姻中介來控制,而不是你主動去找去控制尋找,由中介為你尋找(過程你毫不知情),你選擇是否接受中介為你匹配到的對象。這個過程中主動找理想對象的控制權從你到中介為:控制反轉;中介輸出給你的對象為:依賴註入;
(2)spring的兩種Ioc容器
BeanFactory:
BeanFactory是基礎類型IOC容器。顧名思義,就是生產Bean的工廠。能夠提供完整的IOC服務。沒有特殊指定的話,其默認采用延遲初始化策略。只有當客戶端對象需要訪問容器中的某個受管對象的時候,才對該對象進行初始化和依賴註入操作。因此,相對來說,容器啟動初期的時候速度是比較快的。所需要的資源有限。所以,對資源有限,並且功能要求不是很嚴格的場景,BeanFactory是比較合適的IOC容器。
ApplicationContext:
ApplicationContext是在BeanFactory的基礎上邊構建的,是相對比較高級的容器的實現,除了擁有BeanFactory的所有支持,ApplicationContext還提供了其他的高級特性。例如事件發布、國際化信息支持等。ApplicationContext所管理的對象,在該類型容器啟動之後,默認全部初始化並綁定完成。相對於BeanFactory來說,ApplicationContext會要求更多的系統資源。因為在啟動時就完成了所有的初始化,容器啟動的時間與BeanFactory相比會長一些。因此,ApplicationContext更適用於系統資源充足,並且要求更多功能的場景中。• 資源訪問,如URL和文件 • 事件傳播 • 載入多個(有繼承關系)上下文 ,使得每一個上下文都專註於一個特定的層次,比如應用的 web層
BeanFactroy采用的是延遲加載形式來註入Bean的,即只有在使用到某個Bean時(調用getBean()),才對該Bean進行加載實例化,這樣,我們就不能發現一些存在的Spring的配置問題。
而ApplicationContext則相反,它是在容器啟動時,一次性創建了所有的Bean。在容器啟動時,我們就可以發現Spring中存在的配置錯誤。
(3)Spring IOC 註入方式
3.1 setter註入:
1 <bean id="helloSpring" class="com.one.ssm.impl.HelloSpring"> 2 <!--此處的value的註入是通過set方法--> 3 <property name="who" value="spring"></property> 4 <property name="you" value="123456789"></property> 5 </bean>xml書寫
代碼書寫:
1 public class HelloSpring { 2 //定義who屬性,值通過spring框架進行設置 3 private String who; 4 private String you; 5 public void setYou(String you) { 6 this.you = you; 7 } 8 public void print(){ 9 System.out.println("Hello:"+this.getWho()+"!"+you); 10 } 11 public String getWho() { 12 return who; 13 } 14 public void setWho(String who) { 15 this.who = who; 16 } 17 } 18 測試類: 19 @Test 20 public void print() throws Exception { 21 ApplicationContext context=new ClassPathXmlApplicationContext("classpath:spring/spring-impl.xml"); 22 HelloSpring helloSpring= (HelloSpring) context.getBean("helloSpring"); 23 helloSpring.print(); 24 } 25 結果:Hello:spring!123456789代碼
3.2 構造器註入
1 <!--構造註入實例--> 2 <bean id="math" class="com.one.ssm.impl.structorInjectionTest.MathDemo"></bean> 3 <bean id="english" class="com.one.ssm.impl.structorInjectionTest.EnglishDemo"></bean> 4 <bean id="StudyDemo" class="com.one.ssm.impl.structorInjectionTest.StudyDemo"> 5 <constructor-arg ref="math"/> 6 <constructor-arg ref="english"/> 7 </bean>構造註入xml書寫
代碼書寫:
1 public class EnglishDemo { 2 public void StudyEnglish(){ 3 System.out.println("學習英語。。。。"); 4 } 5 } 6 7 8 public class MathDemo { 9 public void StudyMath(){ 10 System.out.println("學習數學。。。。"); 11 } 12 } 13 14 public class StudyDemo { 15 private MathDemo mathDemo; 16 private EnglishDemo englishDemo; 17 18 //無參構造方法 19 public StudyDemo() { 20 } 21 22 public StudyDemo(MathDemo mathDemo, EnglishDemo englishDemo) { 23 this.mathDemo = mathDemo; 24 this.englishDemo = englishDemo; 25 } 26 27 28 public void study() { 29 mathDemo.StudyMath(); 30 englishDemo.StudyEnglish(); 31 } 32 }構造註入代碼
備註:Spring通過JavaBean的無參構造函數實例化對象,當編寫了帶參的構造方法後,虛擬機不會再提供無參構造方法,為了保證使用,需要自行添加無參構造方法
3.3p命名空間註入
使用前添加聲明:xmlns:p="http://www.springframework.org/schema/p" xml寫法: <bean id="IocTest" class="com.one.ssm.impl.setterInjectionTest.IocTest" p:zhangGa="三天不打鬼子,手都癢癢" p:rod="世界上有2種人,認識2進制和不認識2進制的人"/> 語法:p:屬性名="屬性值" 引用:p:屬性名-ref="bean的Id"
(4)註入過程子標簽的使用
public class User { private String string; private List<String> list; private Set<String> listString; private Map<String,String> map;
子標簽註入:
1 <bean id="user" class="com.one.ssm.impl.collectionPropertyInjection.User"> 2 <!--list或者數組類型的屬性可以用<list>標簽註入--> 3 <property name="list"> 4 <list> 5 <!--定義list數組中的元素--> 6 <value>足球</value> 7 <value>籃球</value> 8 </list> 9 </property> 10 11 <property name="listString"> 12 <!--set類型的集合屬性可以用<set>--> 13 <set> 14 <value>足球</value> 15 <value>籃球</value> 16 </set> 17 </property> 18 19 <property name="map"> 20 <map> 21 <!--定義map中的鍵值對,如果鍵值對是bean對象,把value換成ref--> 22 <entry> 23 <key> 24 <value>football</value> 25 </key> 26 <value>足球</value> 27 </entry> 28 </map> 29 </property> 30 31 <property name="mapString"> 32 <!--Properties類型的屬性用<props>,是簡化了的 <map> 只能指定 String 類型的鍵和值--> 33 <props> 34 <prop key="football">足球</prop> 35 </props> 36 </property> 37 38 <!--註入空字符串--> 39 <!--<property name="string"><value></value></property>--> 40 <!--註入空值--> 41 <property name="string"><null/></property> 42 </bean>xml書寫
(5)備註:
5.1 在子標簽中有特殊符號需要轉換為實體:
<:<
>:>
&:&
‘:&aops;
":"
例如:P&G應該寫成: P&G 或者使用<![CDATA[]]>形式: <![CDATA[P&G]]>
例如:錯誤:<value>P&G</value>,正確:<value><![CDATA[P&G]]></value>或<value>P&G</value>
加載註解定義的bean組件:<context:component-scan base-package="service,dao"> 在使用註解之後,需要使用component-scan標簽掃描註解標註的類,base-package指定需要掃描的基準包,多個包可以使用逗號(,)分開
5.2 使用註解實現IOC:
@Autowired:采用按照類型匹配的方式自動註入,可以省略setter方法,eg: @Autowired private UserDao dao;@Qualifier:如果有多個類型相匹配時,加入,eg: @Autowired @Qualifier("UserDao") private UserDao dao;
@Autowired:
-->對方法或者構造方法的入參就行標註
@Autowired public void setDao(@Qualifier UserDao dao){this.dao=dao}
-->對類中集合類型的成員變量進行標註
@component public class TaskQeue{@Autowired private List<Job> toDoList}:Spring會將Job類型的組件註入到toDoList
@Resource:有一個name屬性值,spring解釋為要註入的Bean的名稱,eg:@Resource(name="userDao")private UserDao dao;
如果沒有指定名稱,@Resource將根據字段名或者setter方法名產生默認的名稱。
5.3 spring中Bean的五個作用域:
singleton:默認值,容器中該Bean的實例只有一個
prototype:每次從容器中獲取Bean時,都會創建一個新的實例,存在線程安全的組件使用
request:用於Web應用環境,針對每次HTTP請求都會創建一個實例
session:用於Web應用環境,同一個會話共享一個實例
global session:僅在porlet的Web應用中使用,同一個全局會話共享一個實例,非porlet環境,等同於session
xml配置為:
<bean id="..." class="..." scope="..."> .... </bean>
-->使用註解指定Bean的作用域
@scope("prototype")
@Service
public class UserService(){}
5.4 基於xml配置spring的自動裝配
傳統:
<bean id="dao" class="com.one.ssm.dao.impl.UserDaoImpl"/>
<bean id="service" class="com.one.ssm.impl.aopTest.UserServiceImpl">
<property name="userDao" ref="dao"></property></bean>
自動裝配:
代替了通過property標簽顯示的指定Bean的依賴關系
<bean id="userMapper" class="com.one.ssm.dao.impl.UserDaoImpl"/>
<bean id="service" class="com.one.ssm.impl.aopTest.UserServiceImpl" autowire="byName"/>
備註:一般都會通過註解@Autowire來實現
以上為個人理解,僅供參考!!!
SpringIOC的概念理解、構造器註入、setter註入、p命名空間註入、IOC容器介紹與比較