spring框架溫習—AOP

AOP 面向切面編程,擴展功能不修改源代碼實現(配置文件)
採用橫向抽取機制,取代了傳統的縱向繼承體系,重複性代碼(性能監視,事務管理)
橫向抽取機制 底層使用橫向代理方式實現的

/*使用jdk動態代理,針對有接口的情況*/
public interface Dao {
	public void add();
}

public class DaoImpl implements Dao {
	public void add(){
		//業務邏輯
	}
}
//目的 增強實現類add方法
//使用動態代理方式創建 接口實現類代理對象(創建和DaoImpl平級的對象,這個對象不是真正對象,而是代理對象,它可以實現和DaoImpl相同的功能)

/*沒有接口的情況*/
public class User {
	public void add(){}
}

//動態代理實現增強add方法
//創建User類的子類的代理對象 在子類裏面調用父類的方法(super完成)完成增強
代理類eg:
public class sUser extends User {
	//使用cglib動態代理,實現沒有接口
	//添加邏輯
	super.add();
}

操作術語:

public class Demo{
	
	public void add(){}
	
	public void update(){}
	
	public void delete(){}
	
	public void find(){}
}

Joinpoint連接點: 指可以被增強的方法(被稱爲連接點),spring中只支持方法類型的連接點
pointcut切入點: 在類中有很多方法可以被增強,實際操作中只增強了類中的某幾個方法,則這些被實際增強的方法稱爲切入點
Advice通知/增強: 被攔截到的連接點Joinpoint之後要做的事情,增強的邏輯稱爲增強,比如擴展日誌功能,這個日誌功能稱爲增強。分爲前置通知(方法前)、後置通知(方法後)、異常通知(方法出現異常)、最終通知(後置通知之後)、環繞通知(方法之前和之後)
**切面:**把增強應用到具體方法上這個過程稱爲切面
其他術語
spring中AOP操作
在spring中進行aop操作,使用aspectj實現,aspectj不是spring的一部分,它和spring一起進行aop操作,spring2.0後增加了Aspectj支持
使用aspectj實現aop有兩種方式
①基於aspectj的xml方式
使用表達式配置切入點
常用表達式
   execution(<訪問修飾符>?<返回類型><方法名>(<參數>)<異常>)
   *代表所有修飾符 空格 增強方法的全路徑(包含他的參數)
   (1)execution(* com.idea.aop.User.add(…))
   (2)execution(* com.idea.aop.User.*(…)) //*代表類中所有方法
   (3)execution(* *.*(…)) //所有類中的所有方法 都被增強
   (4)execution(* save*(…)) //匹配所有save開頭的方法

<!--struts.xml配置文件-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <!-- 所有匹配*.action的請求都由struts2處理 -->
    <constant name="struts.action.extension" value="action" />
    <!-- 是否啓用開發模式 -->
    <constant name="struts.devMode" value="true" />
    <!-- struts配置文件改動後,是否重新加載 -->
    <constant name="struts.configuration.xml.reload" value="true" />
    <!-- 設置瀏覽器是否緩存靜態內容 -->
    <constant name="struts.serve.static.browserCache" value="false" />
    <!-- 請求參數的編碼方式 -->
    <constant name="struts.i18n.encoding" value="utf-8" />
    <!-- 每次HTTP請求系統都重新加載資源文件,有助於開發 -->
    <constant name="struts.i18n.reload" value="true" />
    <!-- 文件上傳最大值 -->
    <constant name="struts.multipart.maxSize" value="104857600" />
    <!-- 讓struts2支持動態方法調用 -->
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <!-- Action名稱中是否還是用斜線 -->
    <constant name="struts.enable.SlashesInActionNames" value="false" />
    <!-- 允許標籤中使用表達式語法 -->
    <constant name="struts.tag.altSyntax" value="true" />
    <!-- 對於WebLogic,Orion,OC4J此屬性應該設置成true -->
    <constant name="struts.dispatcher.parametersWorkaround" value="false" />

    <package name="basePackage" extends="struts-default">


    </package>

</struts>

web.xml配置過濾器

<!--2.1.3以前:
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
期間:
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterr</filter-class>
2.5以後:
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
-->
<!-- 過濾器 -->
  <filter>
  	<filter-name>struts2</filter-name>
  	<filter-class>org.apache.struts.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterr</filter-class>
  </filter>
  
  <filter-mapping>
  	<filter-name>struts2</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
/**
* action
*/
public class UserAction extends ActionSupport {

	@Override
	public String execute() throws Exception {
		
		System.out.println("action");
		ApplicationContext context = 
				new ClassPathXmlApplicationContext("applictionContext.xml");
		UserService userService = (UserService)context.getBean("userService");
		userService.add();
		return NONE;
	}
}

問題:每次訪問action都要加載一次配置文件,功能沒問題,但是影響性能,現在將加載配置文件讓項目啓動時完成(使用監聽器、ServletContext對象,在spring(spring-web jar包)中已經封裝好監聽器,只需配置即可)

<!--web.xml-->
<!-- 指定spring配置文件路徑 -->
  <context-param>
  	<!--名字固定
		ContextLoaderListener類的父類ContextLoader中
		public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
	-->
  	<param-name>contextConfigLocation</param-name>
  	<!--classpath即src根目錄
		配置spring配置文件的全路徑
	-->
	<!--2、部署applicationContext的xml文件-->  
    <!--如果在web.xml中不寫任何參數配置信息,默認的路徑是"/WEB-INF/applicationContext.xml,  
    在WEB-INF目錄下創建的xml文件的名稱必須是applicationContext.xml。  
    如果是要自定義文件名可以在web.xml里加入contextConfigLocation這個context參數:  
    在<param-value> </param-value>裏指定相應的xml文件名,如果有多個xml文件,可以寫在一起並以“,”號分隔。  
    也可以這樣applicationContext-*.xml採用通配符,比如這那個目錄下有applicationContext-ibatis-base.xml,  
    applicationContext-action.xml,applicationContext-ibatis-dao.xml等文件,都會一同被載入。  
    在ContextLoaderListener中關聯了ContextLoader這個類,所以整個加載配置過程由ContextLoader來完成。-->  
  	<param-value>classpath:applictionContext.xml</param-value>
  </context-param>
<!-- 配置監聽器 路徑不用改-->
  <listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

②基於aspectj的註解方式
@Aspect:作用是把當前類標識爲一個切面供容器讀取
@Pointcut:Pointcut是植入Advice的觸發條件。每個Pointcut的定義包括2部分,一是表達式,二是方法簽名。方法簽名必須是 public及void型。可以將Pointcut中的方法看作是一個被Advice引用的助記符,因爲表達式不直觀,因此我們可以通過方法簽名的方式爲 此表達式命名。因此Pointcut中的方法只需要方法簽名,而不需要在方法體內編寫實際代碼。
@Around:環繞增強,相當於MethodInterceptor
@AfterReturning:後置增強,相當於AfterReturningAdvice,方法正常退出時執行
@Before:標識一個前置增強方法,相當於BeforeAdvice的功能,相似功能的還有
@AfterThrowing:異常拋出增強,相當於ThrowsAdvice
@After: final增強,不管是拋出異常或者正常退出都會執行

在這裏插入圖片描述

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