SSH框架學習之Spring ---- 2、認識AOP ! 警告,前方增強怪!
一、AOP底層分析
需求:根據客戶需要,當前的Dao.class中的add()方法,在呼叫之前需要列印一條"開始列印"語句。
以往的做法:
動add的程式碼,該怎麼改就怎麼改。這其實是不符合設計模式的,對於業務的拓展不修改原來的程式碼,這就是AOP思想。
概念
AOP啥意思呢?拓展功能不修改原始碼。這只是通俗理解。
AOP採用橫向抽取機制,取代了傳統的縱向繼承機制(聽不懂~)
傳統的縱向抽取(古板的糟老頭子)
橫向抽取機制
我們創造一個需要 “修改的類的物件” 的代理,在本案例中也就是 Dao dao;的一個代理,然後在代理物件中進行邏輯的修改,保證了Dao類還是原來的程式碼。這裡就用到了動態代理的知識。
動態代理,這是自己的部落格寫的關於動態代理
Spring已經把AOP的底層程式碼封裝好了。接下去就講如何使用。
二、AOP的操作術語(增強怪出現!)
什麼叫增強?
一個方法得到了補充、修改。
本場案例:一個如下的類需要被增強
public class User { public void add() { System.out.println("add......."); } public void delete() { System.out.println("delete......."); } public void query() { System.out.println("query......."); } public void update() { System.out.println("update......."); } }
1、連線點JoinPoint:類裡面的哪些方法可以被增強,那麼這些方法就稱為連線點。
add、delete、query和update這四個方法
2、切入點Pointcut(重點):類裡面有很多的方法可以被增強,但是我們僅僅增強其中幾個。
例如僅僅增強add和update,那麼這兩個就稱為切入點
3、增強(也叫通知)Advice(重要):增強切入點這個動作
比如額外增加一個輸出當前時間的功能,就叫增強。
- 前置通知:在方法之前執行
- 後置通知:在方法之後執行
- 異常通知:
- 最終通知:
- 環繞通知:方法之前和之後執行
4、切面Aspect(重要):把增強用到切入點,把增強應用到具體方法的過程
例如把輸出時間的功能用到add(),這個過程就叫切面
5、其他,瞭解即可
三、Spring中AOP的具體操作
案例: 希望在Book的add執行之前,先執行Mybook的add。以前的做法是在Mybook的add方法內,呼叫book的add方法。
3.1、前期準備:
匯入jar包:
建立Spring核心配置檔案,引入aop的約束
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
建立Book,MyBook物件
public class Book {
public void add() {
System.out.println("add....");
}
}
public class MyBook {
public void before1() {
System.out.println("前置增強...");
}
}
3.2、使用表示式配置切入點
常用的幾種表示式:
execution(<訪問修飾符>?<返回型別><方法名>(<引數>)<異常>)
(1) execution(* cn.itcast.aop.Book.add(…)) // 對add進行增強
(2) execution(* cn.itcast.aop.Book.*(…)) //對所以的方法進行增強
(3) execution(* .(…))
(4) execution(* save*(…) // 匹配所以save開頭的方法
3.3、具體配置
<?xml version="1.0" encoding="UTF-8" ?>
<!--引入schema約束-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1、生成物件-->
<bean id="book" class="cn.itcast.aop.Book"></bean>
<bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
<!--2、配置aop操作-->
<aop:config>
<!--2.1 配置切入點(被增強的方法)
id:給切入點起的名字
expre:通過表示式指定對哪個方法進行增強
-->
<aop:pointcut id="pointcut1" expression="execution(* cn.itcast.aop.Book.*(..)"></aop:pointcut>
<!--2.2 配置切面(增強用在具體方法)
ref:要增強上去的方法所在的bean
-->
<aop:aspect ref="myBook">
<!--配置增強型別
method:哪個方法作為前置增強
pointcut-ref:用到哪個方法上
-->
<aop:before method="before1" pointcut-ref="pointcut1"></aop:before>
</aop:aspect>
</aop:config>
</beans>
測試結果
public void test() {
ApplicationContext context =
new ClassPathXmlApplicationContext("bean3.xml");
Book book = (Book) context.getBean("book");
book.add();
}
//輸出:
前置增強...
add....
環繞增強
四、AOP的註釋寫法
配置的寫法太繁瑣了,於是貼心的Spring又給帶來了一種註釋寫法。
在spring核心配置檔案中,開啟aop操作掃描
<!--生成物件-->
<bean id="book" class="cn.itcast.aop.Book"></bean>
<bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
<!--開啟aop掃描-->
<aop:aspectj-autoproxy/>
在增強類上用註解來實現aop操作
@Aspect
public class MyBook {
@Before(value = "execution(* cn.itcast.aop.Book.*(..))")
public void before1() {
System.out.println("前置增強...");
}
}
總結:程式碼一下子少了很多有沒有!!至此,AOP操作講述完畢,以後遇到需要新增功能,要想起來Sprng的AOP!!