Spring Framework 相比較EJB是一個輕量級的解決方案,是構建企業級應用的一站式解決方案。同時Spring 是模塊化的,允許您只使用您需要的那部分,而無需引入其餘的。您可以在任何 web 框架中引入 IoC 容器,並且您也可以只使用Hibernate或者JDBC。Spring Framework 支持聲明式的事務管理 (transaction management),通過 RMI 或 web services 遠程訪問您的邏輯,以及用於保存數據的各種選項。它提供MVC架構,並且使您能夠將AOP透明地集成到您的軟件中。
Spring 被設計為非侵入式的,這意味著你的邏輯代碼通常不依賴於框架本身。在 integration 層(例如數據訪問層)中,存在對數據訪問技術和 Spring libraries 的一些依賴。然而,從代碼中分離這些依賴是很容易。
1、Spring Framework 簡介
Spring Framework是一個java平臺,為開發java應用程序提供全面的基礎架構支持。由於spring已經提供了基礎架構,因此你只需要專注於應用開發。
1.1、控制反轉和依賴注入
使用面向對象編程的系統中,它的底層都是有N個對象來組成實現的,所有的對象通過彼此之間的合作,最終實現系統的業務邏輯。
隨著業務系統的不斷壯大,對象之間的依賴關係也越來越複雜,經常會出現對象之間的多重依賴性關係,對象之間耦合度越高的系統,必然會出現牽一髮而動全身的情況。
如何降低系統之間、模塊之間和對象之間的耦合度,是軟件工程領域永遠追求的目標之一。軟件轉件Michael Mattson提出了控制反轉(IoC)理論,用來實現對象之間的“解耦”,目前很多J2EE項目都採用了Spring的IoC技術。
1.2、什麼是控制反轉(IoC)
IoC是Inversion of Control的縮寫,可以翻譯成“控制反轉”或者“反轉控制”。IoC理論提出的觀點思想是這樣的:藉助於“第三方”實現具有依賴關係對象之間的解耦。
大家發現了吧,由於引進了第三方的IoC容器,是的A、B、C、D這4個對象之間沒有了耦合關係,對象之間的依賴關係完全交給了Ioc容器。所以,IoC容器成了整個系統的核心,它起到了一種“粘合劑”的作用,把系統中的所有對象粘合在一起。
我們來做個試驗,把上圖中的IoC容器拿掉,整個系統會變成這個樣子:
這時候,A、B、C、D這4個對象之間已經沒有了耦合關係,彼此毫無聯繫,這樣的話,當你在實現A對象邏輯的時候,根本不用去考慮B、C和D了,對象之間的依賴關係已經降低到最低水平。因此,如果使用了IoC容器,對於做系統來說,是一件非常美好的事情,參與開發的工程師只需要關注自己的實現類即可,跟別人沒有任何關係!
我們再來回顧一下IoC的原理,通俗的講一下:
- 在沒有引入IoC容器之前,如果對象A依賴於對象B,那麼對象A在初始化或者運行到某一個功能的時候,自己必須要主動創建對象B或者是使用以前已經創建的對象B。無論是創建還是使用對象B,主動權都在自己的手裡。
- 在引入IoC容器之後呢,對象A和對象B之間失去了直接聯繫,所以,當對象A運行到需要對象B的時候,IoC容器會主動創建一個對象B注入到對象A需要的地方。
通過前後的對比,我們不難看出:對象A獲得依賴對象B的過程,由主動行為變成了被動行為,控制權顛倒過來了,這就是控制反轉(IoC)的含義。
1.3、IoC的應用
IoC是一種思想,它不是一種編程技術,它能夠指導我們如何設計出低耦合的程序。傳統的應用程序都是由我們在類的內部主動創建對象,從而導致類與類之間高耦合,不利進行測試;有了IoC容器之後,把創建和查找控制對象的權限交給了容器,由容器進行注入組合對象,因此,對象與對象之間是 低耦合的。這種結構設計,有利於功能的複用,而且能夠使整個程序的體系結構變得非常靈活。
IoC對於編程帶來的最大改變不是從代碼上,而是從思想上,發生了“主從換位”的變化,要獲取什麼資源都是主動出擊,但是在IoC/DI思想中,應用程序變得被動 了,被動的等待IoC容器來創建並注入它所需要的資源。
1.4、DI(依賴注入),IoC的別名
2004年,Martin Fowler探討了同一個問題,既然IoC是控制反轉,那麼它到底“哪方面被控制反轉了呢?”,經過不斷的分析和探討之後,他得出的結論是“獲得依賴對象的過程被反轉了”。控制被反轉之後,獲得依賴對象的過程由自身管理變為了有IoC容器主動注入。於是,他給“控制反轉”取了一個更合適的名字“依賴注入(Dependency Injection)”。他的結論,實際上給出了IoC的方法:注入。所謂依賴注入,就是由IoC容器在運行期間,動態的將某種依賴關係注入到對象之中。
所以,依賴注入(DI)和控制反轉(IoC)只是從不同的角度來描述同一個事情,就是指通過引入IoC容器,利用依賴注入的方式,實現對象之間的解耦。
2、Spring Framework的體系結構
Spring Framework大概由20個模塊組成,這些模塊包括:Core Container,Data Access/Injection,Web,AOP(Aspect Oriented Programming),Instrumentation,Messaging和Test等。
如下圖所示
3、Spring的入門案例
建立一個基於Maven的Spring IoC項目,以Idea 和 maven創建的一個普通的Java項目為例。
3.1 創建項目(Maven)
此處不選取任何模板,只是創建一個Java項目
這樣一個Maven的spring對象就創建好了。
3.2 導入Pom.xml依賴包
<code>
<project> 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>org.example/<groupid>
<artifactid>learning-spring01/<artifactid>
<version>1.0-SNAPSHOT/<version>
<properties>
<project.build.sourceencoding>UTF-8/<project.build.sourceencoding>
<java.version>1.8/<java.version>
<junit.version>4.12/<junit.version>
<spring-framework.version>4.3.18.RELEASE/<spring-framework.version>
<log4j.version>1.2.17/<log4j.version>
/<properties>
<dependencies>
<dependency>
<groupid>org.springframework/<groupid>
<artifactid>spring-context/<artifactid>
<version>${spring-framework.version}/<version>
/<dependency>
<dependency>
<groupid>log4j/<groupid>
<artifactid>log4j/<artifactid>
<version>${log4j.version}/<version>
/<dependency>
<dependency>
<groupid>org.springframework/<groupid>
<artifactid>spring-test/<artifactid>
<version>${spring-framework.version}/<version>
<scope>test/<scope>
/<dependency>
<dependency>
<groupid>junit/<groupid>
<artifactid>junit/<artifactid>
<version>${junit.version}/<version>
<scope>compile/<scope>
/<dependency>
/<dependencies>
<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins/<groupid>
<artifactid>maven-compiler-plugin/<artifactid>
<version>3.8.0/<version>
<executions>
<execution>
compile
<phase>compile/<phase>
<goals>
<goal>compile/<goal>
/<goals>
/<execution>
<execution>
testCompile
<phase>test-compile/<phase>
<goals>
<goal>testCompile/<goal>
/<goals>
/<execution>
/<executions>
<configuration>
<source>${java.version}/<source>
<target>${java.version}/<target>
/<configuration>
/<plugin>
/<plugins>
/<build>
/<project>/<code>
3.3 創建對象
目標:使用spring創建對象,為屬性賦值
Student.java
<code>package com.bigdata.bean;
public class Student {
private String stuId;
private String stuName;
private Integer age;
public String getStuId() {
return stuId;
}
public void setStuId(String stuId) {
this.stuId = stuId;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"stuId='" + stuId + '\\'' +
", stuName='" + stuName + '\\'' +
", age=" + age +
'}';
}
}
/<code>
3.4 編寫配置文件,將對象註冊到容器中
配置文件的名字和路徑都可以任意,建議resources/applicationContext.xml
導入約束
<code>
<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">
<bean>
<property>
<property>
<property>
/<bean>
/<beans>/<code>
3.5 配置log4j.properties
<code>log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c]- %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c]- %m%n/<code>
3.6 測試,通過Spring的IOC容器創建Student類實例
<code>package com.bigdata.ioc.test;
import com.bigdata.bean.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class IoCTest {
// 1.創建IOC容器對象
ApplicationContext bean = new ClassPathXmlApplicationContext("applicationContext.xml");
@Test
public void testIoCBean() {
//2.根據id值獲取bean實例對象
Student student = (Student)bean.getBean("student");
//3.打印Bean
System.out.println(student);
}
}
/<code>
閱讀更多 大數據漫路求索 的文章