寫在前面
- 此係列爲筆者學習整理各大神代碼、網上資料等總結而成,並非純原創,更像學習筆記,水平一般,希望指正
- 什麼是spring?
- Spring是一個輕量級的控制反轉(Ioc)和麪向切面(AOP)的容器框架,存在的目的是構建輕量級的J2EE應用
- Spring以一種非侵入式的方式管理你的代碼,Spring提倡“最少侵入”,這也意味着可以適當的時候安裝和卸載
- Spring目的:解決企業應用開發的複雜性功能:使用基本的JavaBean代替EJB(企業級javabean),提供了更多的企業應用功能適用範圍:任何Java應用
- 引入:spring示例
- 引入jar包:
spring-aop-3.2.4.RELEASE.jar
spring-beans-3.2.4.RELEASE.jar
spring-context-3.2.4.RELEASE.jar
spring-core-3.2.4.RELEASE.jar
spring-expression-3.2.4.RELEASE.jar
spring-test-3.2.4.RELEASE.jar
spring-web-3.2.4.RELEASE.jar
以上jar只給出示例包,具體情況請讀者自行決定,這裏給出下載地址
爲方便maven使用者,這裏給出maven配置詳細
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ssm.demo</groupId>
<artifactId>ssm-demo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>ssm-demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring.version>4.2.4.RELEASE</spring.version>
<java.version>1.8</java.version>
<jdbc.driver.version>5.1.38</jdbc.driver.version>
<aspectj.version>1.7.4</aspectj.version>
<javax.servlet-api.version>3.1.0</javax.servlet-api.version>
<jsp-api.version>2.2</jsp-api.version>
<jstl.version>1.2</jstl.version>
<mybatis.version>3.2.5</mybatis.version>
<mybatis-spring.version>1.2.2</mybatis-spring.version>
<maven.test.skip>true</maven.test.skip>
</properties>
<dependencies>
<!-- Begin: spring依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- End: spring依賴 -->
<!-- Begin: springmvc依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- End: springmvc依賴 -->
<!-- Begin: mybatis依賴 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!-- End: mybatis依賴 -->
<!-- Begin: 數據庫依賴包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${jdbc.driver.version}</version>
<scope>runtime</scope>
</dependency>
<!-- End: 數據庫依賴包 -->
<!-- Begin: aspectj相關jar包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- End: aspectj相關jar包-->
<!-- Begin: Servlet相關依賴包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!-- End: Servlet相關依賴包 -->
</dependencies>
<build>
<finalName>ssm-demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 基礎代碼示例:
ExecuteStrAction 接口
package service;
public interface ExecuteStrAction {
public String execute(String str);
}
ExecuteStrAction接口的兩個實現:UpperAction、LowerAction
package service.imp;
import service.ExecuteStrAction;
public class UpperAction implements ExecuteStrAction {
private String message;
/**
* TODO 轉換爲大寫
* @param str
* @return
*/
@Override
public String execute(String str) {
return (getMessage()+str).toUpperCase();
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package service.imp;
import service.ExecuteStrAction;
public class LowerAction implements ExecuteStrAction {
private String message;
private String desc;
/**
* TODO 轉換成小寫
* @param str
* @return
*/
@Override
public String execute(String str) {
return (getMessage()+str).toLowerCase();
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
spring配置文件:bean.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:context="http://www.springframework.org/schema/context"
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">
<context:annotation-config />
<bean id="TheAction" class="service.imp.UpperAction"
scope="singleton"
>
<property name="message">
<value>HeLLo</value>
</property>
<!--<property name="desc">
<null></null>
</property>-->
</bean>
</beans>
測試代碼:
package action;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import service.ExecuteStrAction;
public class TestQuickStart {
public static void main(String[] args) {
/*ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:bean.xml");
ApplicationContext theAction = (ApplicationContext)ctx.getBean("TheAction");
System.out.println(theAction.execute("Rod Johnson"));*/
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
BeanFactory beanFactory = context;
ExecuteStrAction action = (ExecuteStrAction)beanFactory.getBean("TheAction");
System.out.println(action.execute("Rod Johnson"));
}
}
此示例代碼註釋內外部分爲創建ApplicationContext的兩種不同方式,一般使用未註釋部分寫法
運行結果爲:HELLOROD JOHNSON
將bean.xml class屬性設置爲class="service.imp.LowerAction"
運行結果爲:hellorod johnson
- Spring有什麼好處?
根據上面的示例我們可以看到在我們所有的代碼中(除了測試代碼外),並沒有出現Spring的任何組件;
UpperAction和LowerAction的Message屬性均由Spring通過讀取配置文件(bean.xml)動態設置。客戶代碼(這裏就是我們的測試代碼)僅僅面向接口編程,而無需知道實現類的具體名稱。同時,我們可以很簡單的通過修改配置文件來切換具體的底層實現類。(比如此例子中的UpperAction和LowerAction)
以上所述,對於我們開發有什麼實際好處呢?
我們的組件並不需要實現框架指定的接口,因此可以輕鬆的將組件從Spring中脫離,甚至不需要任何修改(非侵入式設計)
其次,組件間的依賴關係減少,極大改善了代碼的可重用性。
非侵入式設計
在這裏插一句,關於侵入式和非侵入式設計,侵入式設計具體表現爲當使用框架時需要繼承(或其他方式)框架的類,比如Struts2.
而非侵入式設計具體表現爲不需要繼承(比如例子中出現的UpperAction、LowerAction並沒有出現spring組件,只是通過配置文件改變了配置)
下面再給出一個例子詳細解釋非侵入設計帶來的好處:
低侵入降低耦合性:例如現在有一個接口 IProductDAO,有一個實現類ProductDAOImpl(於JDBC的實現)。當需要把項目中用到的ProductDAOImpl全部替換成ProductDAOHibernateImpl並保留ProductDAOImpl類時出現了問題:如果項目中有N個地方使用到了new ProductDAOImpl(),就要替換N個地方,耦合性高不容易維護。
對象依賴關係比較繁瑣:下面是一個員工類,需要用到員工的service和部門的service,那麼此時這個員工類依賴於這兩個service;依賴關係太多的時候不容易配置,spring能夠很好的解決這個問題
public class EmployeeAction{
private IEmpolyeeService service;
private IDepartmentService departmentService;
}
Spring通過依賴注入模式,將依賴關係從編碼中脫離出來,從而大大降低了組件之間的耦合,實現了組件真正意義上的即插即用。這也是Spring最具價值的特性之一。
面向接口編程。
誠然,即使沒有Spring,實現面向接口的設計也不困難。Spring對於面向接口設計的意義,在於它爲面向接口編程提供了一個更加自然的平臺。基於Spring開發,程序員會自然而然傾向於使用接口來定義不同層次之間的關聯關係,這種自發的傾向性,來自於Spring所提供的簡單舒適的依賴注入實現。Spring使得接口的定義和使用不再像傳統編碼過程中那麼繁瑣(傳統編碼過程中,引入一個接口,往往也意味着同時要引入一個Factory類,也許還有一個額外的配置文件及其讀寫代碼)。
Spring涵蓋了應用系統開發所涉及的大多數技術範疇,包括MVC、ORM以及Remote Interface等,這些技術往往貫穿了大多數應用系統的開發過程。Spring從開發者的角度對這些技術內容進行了進一步的封裝和抽象,使得應用開發更爲簡便。在筆者的開發工作中,藉助Spring提供的豐富類庫,相對傳統開發模式,大大節省了編碼量(平均1/3強,對於ORM和Remote層也許更多)。
其次,Spring並非一個強制性框架,它提供了很多獨立的組件可供選擇。如筆者在一些項目中,就僅引用了Spring的ORM模板機制對數據存取層進行處理,並取得了相當理想的效果。