第一章 Spring Framework概述

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理論提出的觀點思想是這樣的:藉助於“第三方”實現具有依賴關係對象之間的解耦。

第一章 Spring Framework概述

IoC解耦過程

大家發現了吧,由於引進了第三方的IoC容器,是的A、B、C、D這4個對象之間沒有了耦合關係,對象之間的依賴關係完全交給了Ioc容器。所以,IoC容器成了整個系統的核心,它起到了一種“粘合劑”的作用,把系統中的所有對象粘合在一起。

我們來做個試驗,把上圖中的IoC容器拿掉,整個系統會變成這個樣子:

第一章 Spring Framework概述

去掉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等。

如下圖所示

第一章 Spring Framework概述

Spring Framework 架構

3、Spring的入門案例

建立一個基於Maven的Spring IoC項目,以Idea 和 maven創建的一個普通的Java項目為例。

3.1 創建項目(Maven)


第一章 Spring Framework概述

此處不選取任何模板,只是創建一個Java項目

第一章 Spring Framework概述


第一章 Spring Framework概述

這樣一個Maven的spring對象就創建好了。


第一章 Spring Framework概述

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>


第一章 Spring Framework概述



分享到:


相關文章: