Spring框架的ioc和aop介紹

----------------------------------------------------------------------------------------------------------------------------------------------------------------        

我們在學習的時候,首先想到的肯定是查閱各種資料來系統學習一下,但是最後我麼往往會發現,不管是哪的資料依然是看不懂(o(╯□╰)o)---------------------所以本文章只介紹Spring的最基本的原理,至於後續的知識,之後再介紹,剛剛接觸Spring的同學不妨看一看本篇總結,也許會對你很有幫助~~大佬們如果看到錯誤的話,請開始你們的批評與指正~~(*^▽^*)。學習就是這麼一個過程,不斷地總結,發現錯誤,總結

------------------------------------------------------------------------------------------------------------------------------------------------------------------

       首先,我們來一句網上或者書上都有的關於Spring的一句官話。這也是剛剛學習Spring的初學者最先看到的一句話:

       Spring是一個輕量級控制反轉(IoC)和麪向切面(AOP)的容器框架

       呃。。。。。看不懂。。。。因爲每個名詞所包含的內涵和邏輯都是可以寫好幾篇文章的,接下來我就給大家整理一下

       一、輕量級,輕量級是比較好理解的(這裏直接搬來百度上的解釋了):從大小與開銷兩方面而言Spring都是輕量的。完整的Spring框架可以在一個大小隻有1MB多的JAR文件裏發佈。並且Spring所需的處理開銷也是微不足道的。此外,Spring是非侵入式的:典型地,Spring應用中的對象不依賴於Spring的特定類。

      二、控制反轉(ioc):

             控制反轉這個詞晦澀難懂,不過重要的是,我們需要理解爲什麼是反轉?

           (有沒有更暈了?彆着急,我們慢慢來)。

            在這裏我舉一個不太成熟的小例子:

             比如說孫毅弟弟大學畢業之後北漂到北京工作,他需要找一個房子來住,下邊是示意圖。而這時候,房子就是我們需要調用的類(爲了更好的和下邊對應這裏寫作user類),而孫毅弟弟就是調用房子類的servlet類,下邊是示意圖:

                                                         

          而使用了ioc之後就是相當於,在孫毅弟弟和房源之間增加了一個房屋中介,這個房屋中介就是我們的ioc容器(這裏注意,ioc是一個概念,而ioc容器是一種技術實現):

                                                

      實現ioc的其中的一個很重要的技術是依賴注入(DI),孫毅弟弟依賴房源,房屋中介將自己管理着的房源注入孫毅弟弟。

 

爲了更好地理解控制反轉的思想,首先我們先來看一下平時我們在進行類的調用時我們是怎麼做的。這裏用用戶(user類)來舉例:

//用戶類
public Class UserService{
   //方法add:增加一個用戶
    public void add(){
      //增加一個用戶操作*****
   }
}


/*現在我們要在Servlet類中調用User接口來增加一個用戶了*/

UserService user=new UserService();

user.add();

(我們的調用的場景可以想象成項目構建時我們的controll層調用前一層Service時的接口的場景,或者其它層)看起來這樣的調用方式萬事大吉了,實際上沒有學框架前剛剛接觸JavaEE時也是這樣做的。

   但是我們來思考一下:我們調用User類的add()方法不只是調用一次,我們可能在十個甚至是上百個Servlet中來聲明User類來調用add()方法,假如萬一我不調用User類了,而是調用他的子類來滿足不同的需求了,是不是那些調用User類的Servlet都要報錯了呢?我們是不是還得去改那成百個調用,這就暴露出來一個問題,這代碼的耦合度 太高了

  後來那些前輩專家們,爲了解決這個耦合的問題,就創造出來一種解決方法:工廠模式。

  工廠模式:我建立一個工廠類,在工廠類中調用User類中的add方法來增加一個用戶,當我User類改變的時候,我就只要改變一下工廠類中的調用就可以了。以下是上面代碼解耦合之後的代碼:

//被調用的Service類
public Class userService{
  pubilc void add(){}
}

//創建一個工廠類Factory類,直接返回的是userService類
public Class Factory{
  public static userService getuserService(){
  return new userService();
}
//Servlet中調用
public Class userServlet{
  userServive s=Factory.getuserService;
}
}

有沒有發現,如果我的userService類要改變,我就只要改變一下工廠類就可以了?爲了更深入的理解工廠模式,我們再來看一個例子:

//創建一個接口:
public interface Shape {
   void draw();
}
//使用接口實現各種類
   //1.
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}   
  //2.
public class Square implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}
 //3.
  public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}


//現在創建工廠類:
public class ShapeFactory {
    
   //使用 getShape 方法獲取形狀類型的對象
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
}

//使用工廠:
public class FactoryPatternDemo {
 
   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();
 
      //獲取 Circle 的對象,並調用它的 draw 方法
      Shape shape1 = shapeFactory.getShape("CIRCLE");
 
      //調用 Circle 的 draw 方法
      shape1.draw();
 
      //獲取 Rectangle 的對象,並調用它的 draw 方法
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
      //調用 Rectangle 的 draw 方法
      shape2.draw();
 
      //獲取 Square 的對象,並調用它的 draw 方法
      Shape shape3 = shapeFactory.getShape("SQUARE");
 
      //調用 Square 的 draw 方法
      shape3.draw();
   }
}

/**********--------得到結果----------*********/
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.



   到這裏,相信我們對工廠模式都有一個比較深刻的瞭解了,但是工廠模式和我們的Spring框架有什麼關係呢?其實我們的ioc的依賴注入和工場模式的思想非常的相似,可以理解爲我們的ioc的控制反轉就是用工廠模式的思想來實現的,換句話說工廠模式就是實現ioc的技術之一,只不過不僅僅是工廠模式就是了,不過我們只需要配置就好了。

 

重點來了:現在正式來介紹我們的ioc,我們的ioc用到的技術(1)xml配置文件(2)dom4j解析xml(3)工廠模式(4)反射機制

 

   1.創建xml配置文件

<bean id="userService"    class="cn.itcast.userService">

  2.

(2)創建一個工廠類:(使用的是dom4j解析配置文件+反射機制)

     public class Factory{
      public static UserService getService(){
       1.使用dom4j解析xml文件中的bean類
          根據id值userService,得到id 對應的class屬性值 賦給一個字符串
          String className="class屬性值"   ————注意這裏和bean中的路徑是對應的
          
       2.//使用反射機制創建對象

          class clazz = class.forName("className");
           //創建類的對象
          UserService service = clazz.newInstance();    //這個方式得到的就是反射中的對象
          return service;

}

}

     當我們再想使用這個類的時候,就使用這個工廠類~

     到這裏大家是不是明白了Spring框架的ioc了呢?總的來說,Spring的很重要的一個功能就是降低類之間的耦合度,而Spring實現所需要的技術有:(1)xml配置文件(2)dom4j解析xml文件(3)工廠模式 (4)反射

 

 

二、下邊我們來介紹一下Spring的aop的原理:

          官方介紹:aop的意思即是面向切面的編程。

           面向切面編程指的就是如果我要在我原有的代碼中拓展功能,我只需要修改配置即可,而不需要修改源代碼。

          和往常一樣,我們先來用一個淺顯易懂的例子來介紹我們的aop的原理。

         孫毅弟弟作爲一個新入職的小碼農 現在新建一個用戶的類,這個類中有一個方法add(),而這個方法的功能是,向我們的數據庫中添加一條數據,即一個用戶:

public Class User{
   //添加用戶
    public void add(){
    /*添加進數據庫的操作*/
 }
}

         現在,領導要我添加一個功能,這個功能是在每次我向數據庫中添加數據時,在拓展一個添加日誌的功能,於是孫毅弟弟就打開了我們的源代碼(上邊的User類)開始改

public Class User{
   //添加用戶
    public void add(){
    /*添加進數據庫的操作*/
    /*添加日誌的操作*/
 }
}

但是每次領導讓孫毅弟弟添加新功能時,孫毅弟弟都要從項目的一大堆類,一大堆代碼中去找到相應的類,然後再到對應的地方修改源碼,,,孫毅弟弟覺得太麻煩了,於是他想出了一個之前學過的辦法:縱向抽取

  縱向抽取:就是繼承

 

 

 

 

 

   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章