Spring核心概念

 Spring IoC

  Spring IoC就是控制反轉,也被稱爲依賴注入(Dependency Injection, DI),是面向對象編程中的一種設計理念,用來下降程序代碼之間的耦合度。正則表達式

  依賴是什麼:算法

      依賴就是在代碼中經過局部變量、方法參數、返回值等創建的對於其餘對象的調用關係。spring

 1 /**
 2  * @content 接口
 3  * @author Gawain
 4  * @date 2017-8-15下午8:02:37
 5  */
 6 public interface DependDemo {
 7     /**
 8      * 顯示信息
 9      */
10     void showInfo();
11 }
12 
13 /**
14  * @content 實現類
15  * @author Gawain
16  * @date 2017-8-15下午8:02:30
17  */
18 public class DependDemoImpl implements DependDemo {
19     /**
20      * 實現方法
21      */
22     @Override
23     public void showInfo() {
24         System.out.println("你好");
25     }
26 }
27 
28 /**
29  * @content 測試類
30  * @author Gawain
31  * @date 2017-8-15下午8:02:09
32  */
33 public class Demo {
34     public static void main(String[] args) {
35         //實例化依賴的對象,此時,Demo類依賴於DependDemoImpl類
36         DependDemo demo = new DependDemoImpl();
37         //調用方法
38         demo.showInfo();
39     }
40 }
例子

      經過上面的代碼能夠看出,Demo類和DependDemoImpl類高度耦合,若是需求變化須要替換DependDemo接口的實現類DependDemoImpl的話,那麼Demo中的代碼也須要進行改動。編程

  解決方法(控制反轉):設計模式

      建立一個對象工廠,將建立實例的工做交給工廠去作,得到對象時不經過new的方式而是經過工廠來得到對象。數據結構

 1 /**
 2  * @content 對象工廠
 3  * @author Gawain
 4  * @date 2017-8-15下午8:11:27
 5  */
 6 public class Factory {
 7     /**
 8      * 返回對象實例
 9      * @return
10      */
11     public static DependDemo getDepend() {
12         return new DependDemoImpl();
13     }
14 }
15 
16 /**
17  * @content 測試類
18  * @author Gawain
19  * @date 2017-8-15下午8:02:09
20  */
21 public class Demo {
22     public static void main(String[] args) {
23         //經過對象工廠得到實例
24         DependDemo demo = Factory.getDepend();
25         //調用方法
26         demo.showInfo();
27     }
28 }
工廠例子

      經過上面的代碼能夠看出,Demo類再也不依靠自身的代碼去得到所依賴的具體的DependDemo對象,而是將這一工做交給了對象工廠去作,若是DependDemo接口的實現類須要替換的話,只要在工廠類修改代碼便可。此時由工廠來控制建立對象而不是Demo自己,這就是控制反轉。app

      按照上面的方法雖然能夠解決問題,可是大量的工廠類會被引入到開發過程當中,大大的增長了開發的工做量。此時咱們就須要用到Spring了。框架

      Spring爲咱們提供了完整的IoC實現,讓咱們得以專一於業務類和DAO類的設計。數據結構和算法

開發Spring項目

  1.下載Spring的jar包並添加到項目中。也可使用MyEclipse來簡化這一步驟。右擊項目,選擇MyEclipse-->Add Spring Capabilities...而後直接點擊Finish。ide

      

  2.編寫Spring配置文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans
 3     xmlns="http://www.springframework.org/schema/beans"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xmlns:p="http://www.springframework.org/schema/p"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans
 7     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
 8     <!-- 經過bean元素聲明須要Spring建立的實例。該實例的類型經過class屬性指定,並經過id屬性爲該實例指定一個名稱,以便於訪問 -->
 9     <bean id="dependDemo" class="com.jazz.demo.DependDemoImpl"/>
10 </beans>
applicationContext.xml配置文件

        補充:

          1.applicationContext.xml是MyEclipse自動幫你添加的。若是你是本身導的jar包的話,這一文件需本身手動建立。

          2.上述代碼中的id屬性也可使用name屬性來完成相同的工做。兩者的不一樣之處在於id屬性只能指定一個名稱,而name屬性能夠指定多個名稱,多個名稱之間使用空格或者逗號隔開。

          3.class屬性是類的全限定類名。

  3.編寫代碼經過Spring獲取DependDemo實例

 1 import org.springframework.context.ApplicationContext;
 2 import org.springframework.context.support.ClassPathXmlApplicationContext;
 3 
 4 /**
 5  * @content 測試類
 6  * @author Gawain
 7  * @date 2017-8-15下午8:02:09
 8  */
 9 public class Demo {
10     public static void main(String[] args) {
11         //經過ClassPathXmlApplicationContext實例化Spring的上下文
12         ApplicationContext con = new ClassPathXmlApplicationContext("applicationContext.xml");
13         //經過ApplicationContext的getBean()方法根據id來獲取bean的實例
14         DependDemo demo = con.getBean("dependDemo", DependDemoImpl.class);
15         //調用方法
16         demo.showInfo();
17     }
18 }
經過SpringIoC容器獲取對象實例

       補充:

           1.在上面的代碼中,ApplicationContext是一個接口,負責讀取Spring配置文件,管理對象的加載、生成,維護Bean對象與Bean對象之間的依賴關係,負責Bean的生命週期等。

           2.ClassPathXmlApplicationContext是ApplicationContext接口的實現類,用於從classpath路徑中讀取Spring配置文件。classpath路徑就是src文件夾。

           3.寫在配置文件中的Bean會在ClassPathXmlApplicationContext加載Spring配置文件時建立生成。

小結:

  Spring IoC它就是一個容器,負責管理Bean的建立以及管理Bean與Bean之間的關係等等。


 

依賴注入

   依賴注入是什麼?

      依賴注入就是將Bean的建立以及爲屬性賦值的工做交給Spring容器來作,從而避免組件之間以硬編碼的方式耦合在一塊兒。

   上文提到過,Spring IoC不只能夠管理對象的加載與生成,還能夠管理Bean與Bean之間的依賴關係。除此以外,還能夠在建立Bean時爲Bean中的屬性賦初值。

   下面再寫一個小例子演示一下依賴注入。

 1 /**
 2  * @content 書實體類
 3  * @author Gawain
 4  * @date 2017-8-15下午9:16:43
 5  */
 6 public class Book {
 7     //書籍名稱
 8     private String bookName;
 9     //重寫toString方法
10     @Override
11     public String toString() {
12         return "Book [bookName=" + bookName + "]";
13     }
14 
15     public String getBookName() {
16         return bookName;
17     }
18 
19     public void setBookName(String bookName) {
20         this.bookName = bookName;
21     }
22 }
23 
24 
25 /**
26  * @content 用戶實體類
27  * @author Gawain
28  * @date 2017-8-15下午9:15:52
29  */
30 public class User {
31     //姓名
32     private String name;
33     //年齡
34     private int age;
35     //正在讀的書籍
36     private Book book;
37     //重寫toString方法
38     @Override
39     public String toString() {
40         return "User [name=" + name + ", age=" + age + ", book=" + book + "]";
41     }
42     public String getName() {
43         return name;
44     }
45     public void setName(String name) {
46         this.name = name;
47     }
48     public int getAge() {
49         return age;
50     }
51     public void setAge(int age) {
52         this.age = age;
53     }
54     public Book getBook() {
55         return book;
56     }
57     public void setBook(Book book) {
58         this.book = book;
59     }
60 }
實體類
 1 /**
 2  * @content 業務邏輯層接口
 3  * @author Gawain
 4  * @date 2017-8-15下午9:13:48
 5  */
 6 public interface UserService {
 7     /**
 8      * 顯示信息
 9      */
10     void showInfo();
11 }
12 
13 
14 /**
15  * @content 業務邏輯層實現類
16  * @author Gawain
17  * @date 2017-8-15下午9:39:25
18  */
19 public class UserServiceImpl implements UserService {
20     private User user;
21     public User getUser() {
22         return user;
23     }
24     public void setUser(User user) {
25         this.user = user;
26     }
27     //顯示用戶信息
28     @Override
29     public void showInfo() {
30         System.out.println(user);
31     }
32 }
業務邏輯層
 1 /**
 2  * @content user控制層,此處做爲測試類
 3  * @author Gawain
 4  * @date 2017-8-15下午9:31:35
 5  */
 6 public class UserController {
 7     public static void main(String[] args) {
 8         ApplicationContext con = new ClassPathXmlApplicationContext("applicationContext.xml");
 9         UserService userService = con.getBean("userService", UserServiceImpl.class);
10         userService.showInfo();
11     }
12 }
測試
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans
 3     xmlns="http://www.springframework.org/schema/beans"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xmlns:p="http://www.springframework.org/schema/p"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans
 7     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
 8     <!-- 經過bean元素聲明須要Spring建立的實例。該實例的類型經過class屬性指定,並經過id屬性爲該實例指定一個名稱,以便於訪問 -->
 9     <bean id="dependDemo" class="com.jazz.demo.DependDemoImpl"/>
10     <!-- 聲明book對象 -->
11     <bean id="book" class="com.jazz.pojo.Book">
12         <!-- 爲屬性賦值 -->
13         <property name="bookName" value="Java數據結構和算法" />
14     </bean>
15     <!-- 聲明user對象 -->
16     <bean id="user" class="com.jazz.pojo.User">
17         <property name="name" value="Gawain" />
18         <property name="age" value="18" />
19         <!-- 使用ref引用book對象,添加依賴關係 -->
20         <property name="book" ref="book" />
21     </bean>
22     <!-- 聲明service對象 -->
23     <bean id="userService" class="com.jazz.services.impl.UserServiceImpl">
24         <property name="user" ref="user"/>
25     </bean>
26 </beans>
applicationContext.xml配置文件

       補充:

          1.爲屬性賦值的方式有不少種,除了上文的設值注入外,還有構造注入和p命名空間注入。

              構造注入語法:

                  <constructor-arg index="" value="" />

                  其中value是值,index是指構造方法中的第幾個參數,從0開始。

              p命名空間注入語法:

 1 <beans xmlns="http://www.springframework.org/schema/beans"
 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3 xmlns:p="http://www.springframework.org/schema/p"
 4 xsi:schemaLocation="http://www.springframework.org/schema/beans
 5 http://www.springframework.org/schema/beans/spring-beans.xsd">
 6 <bean name="john-classic" class="com.example.Person">
 7 <property name="name" value="John Doe"/>
 8 <property name="spouse" ref="jane"/>
 9 </bean>
10 <bean name="john-modern"
11 class="com.example.Person"
12 p:name="John Doe"
13 p:spouse-ref="jane"/>
14 <bean name="jane" class="com.example.Person">
15 <property name="name" value="Jane Doe"/>
16 </bean>
17 </beans>
p命名空間注入語法

 

 

                  使用p命名空間注入須要在beans中添加兩個url,基本類型的屬性使用p:屬性名=屬性值的方式注入,引用類型的屬性使用p:屬性名-ref=引用bean的id的方式注入。

          2.除了基本數據類型和自定義數據類型以外,Spring還支持不少數據類型,以下圖所示。此處就不一一列舉了。你們能夠去Spring的幫助文檔中查看。

              

              

小結:

  依賴注入其實就是將對象之間的依賴關係交給Spring來管理和組裝了。不要看它名字說的很「高大上」,其實實現起來很簡單。


 Spring AOP

   Spring AOP簡介:

      Spring AOP就是面向切面編程(Aspect Oriented Programming, AOP),是軟件編程思想發展到必定階段的產物,是面向對象編程(Object Oriented Programming, OOP)的有益補充。AOP通常適用於具備橫切邏輯的場合,例如訪問控制、事務管理、性能檢測等。

  橫切邏輯是什麼:

      你們先來看一段代碼

 1 public class UserController {
 2     //聲明日誌
 3     static Logger log = Logger.getLogger(UserController.class);
 4     public static void main(String[] args) {
 5         //在方法執行前輸出日誌
 6         log.info("顯示用戶信息");
 7         //使用try-catch來進行對異常的處理
 8         try {
 9             ApplicationContext con = new ClassPathXmlApplicationContext("applicationContext.xml");
10             UserService userService = con.getBean("userService", UserServiceImpl.class);
11             userService.showInfo();
12         } catch (Exception e) {
13             log.error("顯示用戶信息失敗", e);
14         }
15     }
16 }
繁瑣的代碼

 

      上面的代碼是一段典型的日誌輸出+異常處理的代碼,從上面的代碼能夠看出,代碼中添加了大量的日誌和異常處理的代碼,而咱們實際的業務代碼只有3行。

      日誌、異常處理、事務控制是一個健壯的業務系統所必須的,可是爲了保證系統健壯可用,就須要在衆多的業務方法中「反覆」編寫相似的代碼,使得本來就很複雜的業務處理代碼變得更加複雜。

      在業務系統中,總有一些散落、滲透到系統各處且不得不處理的事情,這些穿插在既定業務中的操做就是所謂的「橫切邏輯」,也被稱爲「切面」。

      面向切面編程極大的簡化了上面代碼中「重複」但又不得不寫的代碼,可使咱們在不改變原程序的基礎上爲代碼段增長新的功能,對代碼段進行加強處理。它的設計思想來源於代理設計模式。

  Spring AOP基本概念:

      1.切面(Aspect):一個模塊化的橫切邏輯(或橫切關注點),可能會橫切多個對象。

      2.鏈接點(Join Point):程序執行中的某個具體的執行點。

      3.加強處理(Advice):切面在某個特定鏈接點上執行的代碼邏輯。

      4.切入點(Pointcut):對鏈接點的特徵進行描述,可使用正則表達式。加強處理和一個切入點表達式關聯,並在與這個切入點匹配的某個鏈接點上運行。

      5.目標對象(Target object):被一個或多個切面加強的對象。

      6.AOP代理(AOP proxy):由AOP框架所建立的對象,實現執行加強處理方法等功能。

      7.織入(Weaving):將加強處理鏈接到應用程序中的類型或對象上的過程。

      8.加強處理類型:有前置加強、後置加強、環繞加強、異常拋出加強、最終加強等等。這些加強處理實現方式都差很少。


除了上文說的技術以外,spring的幫助文檔也給咱們提供了至關全面且詳細的說明。

相關文章
相關標籤/搜索