Spring 核心IOC, AOP簡介

1、IOC 控制反轉

       IoC叫控制反轉,是Inversion of Control的縮寫,控制反轉是把傳統上由程序代碼直接操控的對象的調用權交給容器,通過容器來實現對象組件的裝配和管理。所謂的"控制反轉"就是對組件對象控制權的轉移,從程序代碼本身轉移到了外部容器,由容器來創建對象並管理對象之間的依賴關係。

    控制反轉——Spring通過一種稱作控制反轉(IoC)的技術促進了松耦合。當應用了IoC,一個對象依賴的其它對象會通過被動的方式傳遞進來,而不是這個對象自己創建或者查找依賴對象,是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。通過IOC反轉控制DI依賴注入完成各個層之間的注入,使得層與層之間實現完全脫耦,增加運行效率利於維護。

    就是把控制權反轉。一般程序都是我們主動new 對象實例,我們擁有控制權。但是通過spring配置,可以使用spring容器幫我們實例化對象,並且也可以注入參數。這裏相當於我們吧我們的控制權交給了spring容器,實現了控制的反轉。

例如:(setter注入)

public class Person{
	private String name;
		
	public void setName(String name){
		this.name = name;
	}
		
	public void info(){
		System.out.println("名字是: " + name);
	}
}

         Spring吧該類部署到Spring容器文件中,在Spring配置文件中增加如下片段(默認spring bean是單例模式)

<bean id = "person" class="con.zds.Person">
	<porperty name="name" value="tom">
</bean>

          在主程序中調用該類就變成了這樣:

Person p = ctx.getBean("person", Person.class);
p.info();

        上面兩行代碼不是直接創建Person實例,而是通過Spring容器獲取Person實例,這正是Spring容器的作用。Spring不僅可以實例化對象,還可以爲對象中的屬性賦值。---這種由Spring容器爲對象設置屬性的方式被稱爲控制反轉IOC

2、DI 依賴注入

   作用:使代碼變得更簡潔、耦合性更小。   

   什麼叫依賴: 所有java應用,他們都是一種典型的依賴型應用。也就是由一些相互協作的對象構成的。Spring把這種互相協作的關係成爲依賴關係。假如A組件調用了B組件的方法,我們可以稱A組件依賴於B組件

   實例:任何一個有實際意義的應用都是有兩個或者更多的類組成,這些類相互協作來完成特定的業務邏輯,通常,每個對象負責管理與自己相互協作的對象的引用,這將會導致高度耦合和難以測試的代碼。如下:

public class Person {    
    private User user;        
    public Person(){        
        user = new User();    
    }       
}

    如上代碼,在構造器中new了一個對象的實例,這使得User和Person緊密耦合在一起,User完全侵入了Person類中。如果在別處也要使用User對象,也會在需要的地方new出來。假如User類有所改變,會導致只要用到User實例的地方都需要更改。

   上面的代碼緊耦合,緊耦合的代碼難以複用,難以理解。 但是一定的耦合也是必須的,完全沒有耦合的代碼什麼也做不了。使用依賴注入DI能很好解決這個問題。

public class Person{
	private User user;
	public Person(User user){
		this.user = user;
	}
}

上面就是依賴注入的方式之一(配置文件是下面的代碼):構造器注入

依賴注入優點:松耦合

  要完成上面的注入必須要通過XML配置bean, 創建應用組件之間的協作的行爲通常稱爲:裝配。Spring有多種裝配Bean的方式,採用XML配置是最常用的方式。下面創建一個applicationContext.xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.ws.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<bean id="person" class="com.zds.Person">
		<constructor-arg ref="user" />
	</bean>
	<bean id="user" class="com.zds.User" />
</beans>

    工作原理:Spring通過上下文(Application Context)裝在Bean的定義並把他們組裝起來。Spring應用上下文全權負責對象的創建和組裝。Spring自帶了幾種應用上下文的實現,他們之間主要的區別僅僅是如何加載它們的配置。因爲applicationContext.xml中的Bean是在XML中聲明的,所以選擇ClassPathXmlApplicationContext作爲擁有上下文是比較合適的。該類加載位於應用系統classpath下的一個或者多個xml文件,ClassPathXmlApplicationContext加載applicationContext.xml,並獲得Knight對象的引用。

裝載Bean,並且注入到業務類中,進行測試,如下:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class KnightMain {
	public static void main(String[] args){
		AppcationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person= (Person)context.getBean("person");
		person.toString();  //用來驗證是否注入,如果沒有會報空指針異常
	}
}

3、AOP 應用切面

  依賴注入讓互相協作的軟件組件保持鬆散耦合,而AOP編程允許你吧遍佈應用各處的功能分離出來形成可重用的組件。比如日誌、事務管理、安全此類的系統服務經常融入到有自身核心業務的組件中去,這些系統服務通常被稱爲橫切關注點,他們總是跨越系統的多個組件。

如下圖:

                                                        

  AOP可以使這些服務模塊化,並以聲明的方式將他們應用到他們需要影響的組件中去。結果是這些組件具有高內聚性以及更加關注自身業務,完全不需要了解可能設計的系統服務的複雜性,總之,AOP確保POJO保持簡單。如下:

         

  我們可以把切面想象爲覆蓋在很多組件之上的一個外殼,應用是由哪些實現各自業務功能的模塊組成。利用AOP,你可以使用各種功能層去包裹核心業務層,這些層以聲明的方式靈活應用到你的系統中,甚至你的核心應用根本不知道他們的存在。這可以將事務和日誌關注點與你的核心業務邏輯分離。

簡單的實例:

public class People {
	public void eatBeforeWan(){
		System.out.println("玩之前,要先喫飯··");
	}
	
	public void watherAfterWan(){
		System.out.println("完之後,要喝水···");
	}
}

上面People這個類有兩個方法,在玩之前之後會分別調用這兩個方法。吧這兩個方法加入你的業務中,如下:

public void happy(){
	knight.eatBeforeWan();
	knight.wan();  //核心業務類
	knight.watherAfterWan();
}

  雖然上面的代碼不太繁瑣,但是可以看出,我不關心玩之前之後幹什麼,我只要業務是“玩”,在我做正事的時候,讓我做一些其他無關的事情,這個總感覺不太好。這裏通過使用AOP,就可以解決這些繁瑣無用的代碼,讓我們只關注核心業務就可以了。

配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.ws.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	<!-- DI 依賴注入配置 -->
	<bean id="person" class="com.zds.Person">
		<constructor-arg ref="user" />
	</bean>
	<bean id="user" class="com.zds.User" />
	
	<!-- AOP 有關配置 -->
	<bean id="minstrel" class="com.springinaction.knights.Minstrel" />
	<aop:config>
		<aop:aspect ref="minstrel"><!-- 定義切面 -->
			<aop:pointcut id="embark" expression="execution(* *.embarkOnuest(..))" /><!-- 
				前置通知 -->
			<aop:before pointcut-ref="embark" method="eatBeforeWan" /><!-- 
				後置通知 -->
			<aop:after pointcut-ref="embark" method="watherAfterWan" />
		</aop:aspect>
	</aop:config>
</beans>















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