對sPRing有所了解的都應該知道,spring貫穿始終的兩個重要的思想,一個是IOC(控制反轉),一個是DI(依賴注入),對于新手而言,這兩個概念比較難理解,我用自己的想法來解釋下
這里先引入兩個概念:耦合性、侵入性。簡單的講:耦合性,在java中表現為類之間的關系,耦合性強說明類之間的依賴關系強;侵入性:框架對代碼的侵入,比如你項目用了struts1,要改框架時發現改的東西太多了,比如actionForm等,所以struts1對代碼的侵入性是很高的。在傳統的java開發中具有高度的耦合性和侵入型。一個項目中,一般一個類都要依賴很多其他的類來完成自己的操作,我們往往采用new這個類的對象來調用他的方法,這樣就造成了兩個類的依賴關系太強,改一個地方,往往牽扯很多類牽扯大量的代碼。侵入性上一段的例子可以明白。當然EJB也可以解決耦合性和侵入性的問題,但是ejb太依賴服務器,屬于重量級的框架。 可以說在這樣的背景下,spring應運而生,一個輕量級的框架,解決傳統企業開發的復雜性;使用普通的javaBean代替EJB技術。可以管理對象和對象之間的依賴關系,我們不需要自己建立對象,把這部分工作全部轉交給容器完成,具有低耦合,對代碼沒有侵略性,對服務器沒有依賴性特點的框架。而這個容器,即IOC.
一個很流行的例子,我換了種說法,這樣更好理解:好比找女朋友,普通的方式是我們依賴各種關系找到這個女朋友(相當于new了對象),有一天分手了,而以前的那些關系也沒有了,要想找到新的女朋友就要依賴新的關系(重新 new另外一個對象),可以想象這個過程很麻煩。于是有了一種新的方式找對象——婚介所,這里就是我們所說的IOC方式,你把你要求的對象的特征告訴婚介所,他會直接給你找到一對象,沒有中間復雜的過程,你只管相處的事情就好了,new的過程不用管,不需要任何依賴關系,即使哪天要換了,再把需要的對象提交給婚介所就行了,你就會得到你想要的新的對象了。事實上,使用ioc方式創建對象的目的,是為了以“被動”的方式形成對象之間的依賴關系。傳統的開發過程中,不管是new,還是普通工廠,都需要目標對象主動創建、主動查找其需要的依賴對象 , 目標對象會將他的精力分散在不必要的非業務邏輯方面。IOC通過DI(依賴注入)把建立好的對象注入到目標對象中。
上文中的婚介所就是ioc管理對象的容器,實際上是一個xml文件,將對象配置在xml里面,通過spring的工廠類進行解析,以“反射”的方式創建對象。 spring IOC容器的關鍵點: * 必須將被管理的對象定義到spring配置文件中 * 必須定義構造函數或setter方法,讓spring將對象注入過來 我們可以通過下面這里例子理解spring ioc的實現。本例使用spring 3.2 1.配置applicationContext.xml
<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.2.xsd"> <bean id="userDao4MySQLImpl" class="com.bjsxt.spring.dao.UserDao4MySqlImpl"/> <bean id="userDao4OracleImpl" class="com.bjsxt.spring.dao.UserDao4OracleImpl"/> <bean id="userManager" class="com.bjsxt.spring.manager.UserManagerImpl"> <!-- 構造方法注入 <constructor-arg ref="userDao4OracleImpl"/> --> <!-- setter方法注入 --> <property name="userDao" ref="userDao4OracleImpl"/> </bean></beans>2.注入的類:package com.bjsxt.spring.dao;public interface UserDao { public void save(String username, String passWord);}package com.bjsxt.spring.dao;public class UserDao4MySqlImpl implements UserDao { public void save(String username, String password) { System.out.println("--------UserDao4MySqlImpl.save()-------"); }}package com.bjsxt.spring.dao;public class UserDao4OracleImpl implements UserDao { public void save(String username, String password) { System.out.println("--------UserDao4OracleImpl.save()-------"); }}3.被注入的類:package com.bjsxt.spring.manager;public interface UserManager { public void save(String username, String password);}package com.bjsxt.spring.manager;import com.bjsxt.spring.dao.UserDao;public class UserManagerImpl implements UserManager { /** * 兩種方式:如果這個類中需要注入對象,先建立對象屬性, * 在寫構造方法或者settet方法。 * */ private UserDao userDao;/* public UserManagerImpl(UserDao userDao) { this.userDao = userDao; } */ public void save(String username, String password) { this.userDao.save(username, password); } public void setUserDao(UserDao userDao) { this.userDao = userDao; }}4.測試類:package com.bjsxt.spring.client;import org.springframework.beans.factory.BeanFactory;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.bjsxt.spring.manager.UserManager;public class Client { public static void main(String[] args) {/* 傳統的通過new對象建立類之間的關系 * UserManager userManager = new UserManagerImpl(new UserDao4OracleImpl()); UserManager userManager = new UserManagerImpl(new UserDao4MySqlImpl()); userManager.save("張三", "123");*//** * IOC思想 通過工廠類解析xml文件,以“反射”的方式創建對象: */ BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); UserManager userManager = (UserManager)factory.getBean("userManager"); userManager.save("張三", "123");/** * IOC思想 實際的執行過程,這也是為什么需要setter方法或構造方法的原因: */// UserManagerImpl userManager = new UserManagerImpl();// userManager.setUserDao(new UserDao4MySqlImpl());// userManager.save("張三", "123"); }}這樣就實現了spring ioc思想。 本文完全個人理解,如有不對的地方,懇請指正。原文鏈接:http://blog.csdn.net/frightingforambition/article/details/47974775
新聞熱點
疑難解答