今天決定要開始總結框架了,雖然之前總結過兩篇,可是思惟是變化的,並且也沒有什麼規定說總結過的東西就不能再總結了,是吧。此次總結我命名爲淺入淺出,主要在於理解框架核心,輕鬆愉快使用框架。html
咱們都學了面向對象,在生活中,當人們須要一件東西時,第一反應就是找東西,例如想吃麪包,如今有兩種狀況,第一種是沒有面包店,第二種是有面包店。第一種狀況就是咱們以前一直遇到的狀況,在沒有面包店的狀況下,最直觀的作法可能就是你按照本身的口味製做麪包,也就是一個麪包須要主動製做,誰想吃了就本身New。而我主要說的是第二種狀況,就是有面包店,你想吃麪包的時候找到麪包店,把本身的口味告訴店家,店家就能夠給你作符合你口味的麪包了。注意:你並無製做麪包,而是由店家制做,可是徹底符合你的口味。java
這是一個很生活的例子,你們都明白,但這裏包含了Spring中很重要的思想——控制反轉,就是把製做麪包的主動權交給店家,麪包就是對象,店家至關於一個大容器,你想要什麼對象,就讓大容器去給你生產,這就是控制反轉思想。mysql
再詳細點,當某個Java對象(調用者,例如你)須要調用另外一個Java對象(被調用者,即被依賴對象,例如麪包)時,在傳統編程模式下,調用者一般會採用「New 被調用者」的代碼方式來建立對象(例如你本身製做麪包)。這種方式會增長調用者與被調用者之間的耦合性,不利於後期代碼的升級和維護。web
當Spring框架出現後,對象的實例再也不由調用者來建立,而是由 Spring容器(例如麪包店)來建立。Spring容器會負責控制程序之間的關係(例如麪包店負責控制你與麪包的關係),而不是由調用者的程序代碼直接控制。這樣,控制權由調用者轉移到Spring容器,控制權發生了反轉,這就是Spring的控制反轉。spring
在以前,咱們須要用構造方法或者set()方法給一些成員變量賦值,從Spring容器角度來看,Spring容器負責將被依賴對象賦值給調用者的成員變量,至關於爲調用者注入它所依賴的實例,這就是Spring的依賴注入。sql
綜上所述,控制反轉是一種經過描述(在Spring中能夠是XML或註解)並經過第三方去產生或獲取特定對象的方式。在Spring中實現控制反轉的是IoC容器,其實現方法是依賴注入。express
看完上面所述,咱們知道實現控制反轉的是Spring IoC容器。Spring IoC容器的設計主要是基於BeanFactory和ApplicationContext兩個接口。編程
先說BeanFactory,它提供了完整的IoC服務支持,是一個管理Bean的工廠,主要負責初始化各類Bean。BeanFactory接口有多個實現類,其中比較經常使用的是org.springframework.beans.factory.xml.XmlBeanFactory,該類會根據XML配置文件中的定義來裝配Bean.因爲BeanFactory實例加載Spring配置文件在實際開發中並很少見,只需瞭解便可,我也不過多解說了。api
再說ApplicationContext,它是BeanFactory的子接口,也稱爲應用上下文,ApplicationContext接口除了包含BeanFactory的全部功能之外,還添加了對國際化、資源訪問、事件傳播等內容的支持。建立ApplicationContext接口實例一般有三種方法:spring-mvc
一、 經過ClassPathXmlApplicationContext建立
二、 經過FileSystemXmlApplicatonContext建立
三、 經過Web服務器實例化ApplicationContext容器
做爲一個初學者,我以爲先會用第一種就能夠了,因此我主要解說第一種,別的等你本身入門後本身看,我只作引導。
ClassPathXmlApplicationContext將從類路徑目錄(src根目錄)中尋找指定的XML配置文件,以下代碼:
public class Test { public static void main(String[] args) { //初始化SPring容器,加載配置文件 ApplicationContext appCon = new ClassPathXmlApplicationContext("spring-config.xml"); //經過容器得到test實例 TestDao tt = (TestDao) appCon.getBean("test"); tt.sayHello(); } }
在Spring中實現IoC容器的方法是依賴注入,依賴注入的做用是在使用Spring框架建立對象時動態地將其所依賴的對象(例如屬性值)注入Bean組件中,Spring框架的依賴注入一般有兩種實現方式,一種是使用構造方法注入,另外一種是使用屬性的setter方法注入。具體且看實例演示
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <!--spring核心依賴--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.1.5.RELEASE</version> </dependency> </dependencies>
package com.my.dao; public interface TestDao { public void sayHello(); }
package com.my.dao.impl; import com.my.dao.TestDao; public class TestDaoImpl implements TestDao { @Override public void sayHello() { System.out.println("Hello Spring!!!"); } }
<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <bean id="testDIDao" class="com.my.dao.impl.TestDaoImpl"/> </beans>
package com.my.test; import com.my.dao.TestDao; import com.my.dao.impl.TestDaoImpl; import com.my.service.TestService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { //調用者本身建立對象 TestDao testDao = new TestDaoImpl(); testDao.sayHello(); //初始化SPring容器,加載配置文件 ApplicationContext appCon = new ClassPathXmlApplicationContext("spring-config.xml"); //經過容器得到test實例 TestDao tt = (TestDao) appCon.getBean("testDIDao"); tt.sayHello(); } }
package com.my.service; public interface TestService { public void sayHello(); }
package com.my.service.impl; import com.my.dao.TestDao; import com.my.service.TestService; public class TestServiceImpl implements TestService { private TestDao testDao; //構造方法,用於實現依賴注入接口對象TestDao public TestServiceImpl(TestDao testDao) { this.testDao = testDao; } @Override public void sayHello() { testDao.sayHello(); } }
<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <!--將指定類TestDaoImpl配置給Spring,讓Spring建立其實例--> <bean id="testDIDao" class="com.my.dao.impl.TestDaoImpl"/> <!--使用構造方法注入--> <bean id="testDIService" class="com.my.service.impl.TestServiceImpl" > <!--將TestDIDao注入到TestDIServiceImpl類的屬性testDao上--> <constructor-arg index="0" ref="testDIDao"/> </bean> </beans>
package com.my.test; import com.my.dao.TestDao; import com.my.dao.impl.TestDaoImpl; import com.my.service.TestService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { //調用者本身建立對象 TestDao testDao = new TestDaoImpl(); testDao.sayHello(); //初始化SPring容器,加載配置文件 ApplicationContext appCon = new ClassPathXmlApplicationContext("spring-config.xml"); //經過容器得到test實例 TestDao tt = (TestDao) appCon.getBean("testDIDao"); tt.sayHello(); //經過容器獲取TestService實例,測試構造方法注入 TestService testService =(TestService) appCon.getBean("testDIService"); testService.sayHello(); } }
package com.my.service.impl; import com.my.dao.TestDao; import com.my.service.TestService; public class TestServiceImpl implements TestService { private TestDao testDao; //添加testDao屬性的setter方法,用於實現依賴注入 public void setTestDao(TestDao testDao){ this.testDao=testDao; } @Override public void sayHello() { testDao.sayHello(); } }
<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <!--將指定類TestDaoImpl配置給Spring,讓Spring建立其實例--> <bean id="testDIDao" class="com.my.dao.impl.TestDaoImpl"/> <!--使用setter方法注入--> <bean id="testDIService" class="com.my.service.impl.TestServiceImpl"> <!--調用TestDIServiceImpl類的setter方法,將TestDao注入到TestServiceImpl類的屬性testDao上--> <property name="testDao" ref="testDIDao"></property> </bean> </beans>
package com.my.test; import com.my.dao.TestDao; import com.my.dao.impl.TestDaoImpl; import com.my.service.TestService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { //調用者本身建立對象 TestDao testDao = new TestDaoImpl(); testDao.sayHello(); //初始化SPring容器,加載配置文件 ApplicationContext appCon = new ClassPathXmlApplicationContext("spring-config.xml"); //經過容器得到test實例 TestDao tt = (TestDao) appCon.getBean("testDIDao"); tt.sayHello(); //經過容器獲取TestService實例,測試setter方法注入 TestService testService =(TestService) appCon.getBean("testDIService"); testService.sayHello(); } }
在Src根目錄下建立Spring配置文件spring-config.xml(文件名隨意,注意後綴.xml)。在配置文件中,constructor-arg元素用於定義類構造方法的參數,index用於定義參數的位置,ref指定某個實例的引用,若是參數是常量值,ref由value代替。
看完此篇後你以爲理解了,能夠看看我之前寫的這幾篇博客,會有幫助的
《沒有平白無故的編程》http://www.javashuo.com/article/p-nmpttkus-ee.html
《路過別錯過》http://www.javashuo.com/article/p-aovgbila-y.html
《spring框架知多少》http://www.javashuo.com/article/p-stscqkaq-cz.html
《用IDEA開發Spring程序》http://www.javashuo.com/article/p-fcdzbkai-bc.html
此篇Spring淺入淺出到此結束,做此篇是爲了讓初學者放下心理枷鎖,先理解,其實挺好理解的,等你有信心後本身學習就能夠了,但願能對一些朋友有所幫助,加油。
*****************************************************************************************************
個人博客園地址:https://www.cnblogs.com/zyx110/
本文已獨家受權給腳本之家(jb51net)公衆號獨家發佈