Spring介紹
Spring是一個開源架構,為瞭解決公司專屬應用程式開發的複雜性而建立的,但現在已將不止應用於公司專屬應用程式,是一個輕量級的控制反轉(Ioc)和面向切面(AOP)的容器架構。
相對於 java 官方重量級的架構 EJB 來說,Spring 是一個輕量級的架構,而且完成功能只需要簡單的 java 類,並且 Spring 開源。
Spring 對主流 java 技術的支援,(持久層Hibernate、JDBC、mybatis)也可以把 Spring 看做 java 應用的綜合體。
Spring 主要應用方案:
SSH: Structs(MVC經典) +Hibernate(持久層技術的代表)+Spring(管理整個工程)
Spring的優點:
1.解耦
以往,service層與dao層耦合,當dao層報錯,service也報錯,service層和dao層嚴重耦合
通過控制反轉(IOC)的技術達到松耦合的目的。
2.AOP編程的支援
3.聲明式的事務支援
4.方便程式的測試
5.方便繼承各種優秀的架構
6.降低了 java EE 使用難度
7.Spring 的源碼可以作為學習範例
Spring 4中文參考文檔:https://github.com/b2gats/stone-docs/blob/master/spring-4-beans.md#beans-factory-properties-detailed 1 面向介面編程 結構設計中,分清層次及調用關係,每層只向外(上層)提供一組功能介面,各層間僅依賴介面而非實作類別 介面實現的變動不影響各層間的調用,這點在公用服務中尤其重要 “面向介面編程”中的“介面”是用於隱藏具體實現和實現多態性的組件
public interface Oninterface { public String hello(String word);}
public class Oninterfaceiml implements Oninterface { @Override public String hello(String word) { return "HEllo world"+word; }}
public class TestMain { public static void main(String[] args) { Oninterface oif = new Oninterfaceiml(); //實現介面類的對象賦值給介面的引用 System.out.println(oif.hello("peng")); }}
2 IOC
對象建立統一託管規範的生命週期管理靈活的依賴注入一致的擷取對象
所有類的建立和銷毀,都由spring控制,也就是說,控制對象生存周期的,不再是引用它的對象,而是spring;對於某個具體的對象而言,以前是它控制其他對象,現在是所有的對象都被spring控制,所以這就是反轉。
IOC本質就是要拋棄new的方法取得對象,通過配置來取得對象。
IOC的理論背景:
當對象A運行到需要對象B時,IOC容器主動建立對象B注入到對象A需要的地方。對象A擷取對象B的行為從主動變為被動行為。
在 spring 的設定檔中,下面的配置
<bean id="date" class="java.util.Date"></bean>
相當於:
Date date = new Date(); 並且 date 是單例的
IOC通俗例子理解
需求:現在一個女孩要找一個男朋友
女孩—>?—>男朋友
a.自己去找
public void getBoyFriend(){ boy = new Boy();//自己建立一個男朋友對象}
b.通過中介(中介是用來得到相關服務的)
BoyFactory 對應的方法:
public Boy getBoy(){ return new Boy();}
Girl 類對應的方法:
public void getBoyFriend(){ boy = BoyFactory.getBoy();}
c.父母包辦
女孩達到年齡後,男朋友就自動出現在面前(spring抽象理解)
private Boy boy;//需要有注入代碼實現public void getBoyFriend(){ this.boy;//外界傳入的一個對象}
IOC注入
3 Bean
在IOC中,所有的對象稱作Bean
使用IOC之後
命名規則
id 的命名由數字、字母和$組成(首字母不能是數字)
java 的屬性命名除了上面的命名規則,還要注意
首字母小寫,接下來單詞的首字母大寫
如果第一個單詞只有一個字母,第二個單詞的首字母也要小寫
<bean id="userDao" class="com.peng.dao.impl.UserDAOImpl" scope="session"></bean><bean id="userDao" class="com.peng.dao.impl.UserDAOImpl" scope="prototype"></bean><bean id="userDao" class="com.peng.dao.impl.UserDAOImpl" scope="singleton"></bean>
| 範圍 |
描述 |
| singleton(預設單例) |
在每個Spring IOC容器中一個bean定義對應一個對象執行個體。 |
| prototype(原型) |
一個bean定義對應多個對象執行個體。 |
| request |
在一次HTTP請求中,一個bean定義對應一個執行個體;即每次HTTP請求將會有各自的bean執行個體, 它們依據某個bean定義建立而成。該範圍僅在基於web的Spring ApplicationContext 情形下有效。 |
| session |
在一個HTTP Session 中,一個bean定義對應一個執行個體。該範圍僅在基於web的SpringApplicationContext 情形下有效 |
| global session |
在一個全域的HTTP Session 中,一個bean定義對應一個執行個體。典型情況下,僅在使用portlet context的時候有效。該範圍僅在基於web的Spring ApplicationContext 情形下有效。 |
在單例中,每個Spring IoC容器只有一個執行個體,無論多少次調用 getBean()方法擷取它,它總是返回同一個執行個體。
CustomerService custA = (CustomerService)context.getBean("customerService");custA.setMessage("Message by custA");System.out.println("Message : " + custA.getMessage());//retrieve it againCustomerService custB = (CustomerService)context.getBean("customerService");System.out.println("Message : " + custB.getMessage());
兩次結果都是第一次第一次設定的結果。
Message : Message by custAMessage : Message by custA
在原型模式中,則是下面的結果
Message : Message by custAMessage : null
Spring自動裝載bean
所謂自動裝配,就是將一個Bean注入到其他Bean的Property中,類似於以下:
<bean id="customer" class="com.lei.common.Customer" autowire="byName" />
Spring支援5種自動裝配模式,如下:
| 類型 |
描述 |
| no |
預設情況下,不自動裝配,通過“ref”attribute手動設定。 |
| buName |
根據Property的Name自動裝配,如果一個bean的name,和另一個bean中的Property的name相同,則自動裝配這個bean到Property中。 |
| byType |
根據Property的資料類型(Type)自動裝配,如果一個bean的資料類型,相容另一個bean中Property的資料類型,則自動裝配。 |
| constructor |
根據建構函式參數的資料類型,進行byType模式的自動裝配。 |
| autodetect |
如果發現預設的建構函式,用constructor模式,否則,用byType模式。 |
執行個體http://www.yiibai.com/spring/spring-auto-wiring-beans-in-xml.html
測試
Customer.java
//package com.peng.dao.impl;public class Customer { private Person person = null; public void setPerson(Person person) { this.person = person; } public void First(){ System.out.println("我是Customer,擷取到的Person方法的內容"+person.getMsg()); }}
Person.java
//package com.peng.dao.impl;public class Person { public String getMsg(){ return "我是person裡的訊息"; }}
applicationContext.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" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > <bean id="userDao" class="com.peng.dao.impl.UserDAOImpl"></bean> <bean id="customer" class="com.peng.dao.impl.Customer" autowire="byName"> </bean> <bean id="person" class="com.peng.dao.impl.Person"></bean> </beans>
Test.java
//package test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.peng.dao.UserDAO;import com.peng.dao.impl.Customer;public class Test { public void testAutoWrie(){ ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); Customer c = context.getBean("customer",Customer.class); c.First(); } public static void main(String[] args) { Test test = new Test(); test.testAutoWrie(); }}
我是Customer,擷取到的Person方法的內容我是person裡的訊息
4 Junit測試
6 AOP面向切面
在軟體業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過先行編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟體開發中的一個熱點,也是Spring架構中的一個重要內容,是函數式編程的一種衍生範型。利用AOP可以對商務邏輯的各個部分進行隔離,從而使得商務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。
配置Spring環境 Spring jar包下載地址
http://repo.spring.io/release/org/springframework/spring/
Spring Tool Suite
Spring Tool Suite下載地址:
http://spring.io/tools/sts/all
Eclipse 版本是 4.6.0,通過Eclipse Marketplace 不能下載sts,安裝會出錯,通過install new software 安裝4.5的update sites 可以成功,但是,new spring project 時,沒有spring project,有spring starter project 等等。
下載的最新版本的4.6.1版本的 Eclipse 可以用4.61版本的
上面的zip包,有的是sts的離線包和Update Site Archives,也只有springsource…才能在install new software時安裝,就是下載的Update Site Archives下的包
下面下載的包並不能離線下載,還找不到原因
建立Java project測試spring
課程學習地址:http://www.chuanke.com/v7232853-198066-1144815.html
這裡Junit 包還用不上,commons -logging的包可以在structs包中找到,沒有這個包會報錯。
UserDAO.java
//package com.peng.dao;public interface UserDAO { public void sayHello();}
UserDAOImpl.java
//package com.peng.dao.impl;import com.peng.dao.UserDAO;public class UserDAOImpl implements UserDAO { @Override public void sayHello() { System.out.println("hello world!"); } }
applicationContext.xml
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.xsd" > <bean id="userDao" class="com.peng.dao.impl.UserDAOImpl"></bean> </beans>
Test.java
//package test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.peng.dao.UserDAO;public class Test { /** * 1.讀取spring的容器 * 2.從spring的容器中尋找我們需要的對象 * 3.從得到的對象中調用需要的方法 * @param args */ public void doFirst(){ //1.讀取Spring的容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //2.從spring容器中尋找我們需要的對象 UserDAO dao = context.getBean("userDao",UserDAO.class); //只需要調用介面,不管它的實現 dao.sayHello(); } public static void main(String[] args) { Test test = new Test(); test.doFirst(); }}
運行結果:
十一月 09, 2016 8:56:20 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh資訊: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7eda2dbb: startup date [Wed Nov 09 20:56:20 CST 2016]; root of context hierarchy十一月 09, 2016 8:56:20 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions資訊: Loading XML bean definitions from class path resource [applicationContext.xml]hello world!
1 利用JUnit測試spring
UserDAO.java
//package com.peng.dao;public interface UserDAO { public void sayHello();}
UserDAOImpl.java
//package com.peng.dao.impl;import com.peng.dao.UserDAO;public class UserDAOImpl implements UserDAO { @Override public void sayHello() { System.out.println("hello world!"); } }
applicationContext.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.xsd" > <bean id="userDao" class="com.peng.dao.impl.UserDAOImpl"></bean> </beans>
TestUserDAO.java
//package junit.com.peng.dao;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;