開始聊聊註解! spring
Spring切面能夠應用5種類型的通知: express
1 Before---在方法被調用以前調用通知 app
2 After--- 在方法完成以後調用通知,不管方法執行是否成功 this
3 After-returning---在方法成功執行以後調用通知! spa
4 After-throwing---在方法拋出異常後調用通知 代理
5 Around---通知包裹了被通知的方法,在被通知的方法調用以前和調用以後執行自定義的行爲。 orm
在目標對象的生命週期裏有多個點能夠進行織入 xml
1 編譯期---切面在目標類編譯時被織入,這種方式須要特殊的編譯器,AspectJ的織入編譯器就是以這種方式植入切面的。 對象
2 類加載期---切面在目標類加載到JVM時被植入,這種方式須要特殊的類加載器,能夠在目標類被引入應用以前加強該目標類的字節碼。 接口
AspectJ5的LTW就支持以這種方式植入切面。
3 運行期---切面在應用運行的某個時刻被植入,通常狀況下,在植入切面時,AOP容器會爲目標對象動態的建立一個代理對象。
Spring AOP就是以這種方式植入切面的。
Spring提供了4種各具特點的AOP支持:
1基於代理的經典AOP
2@AspectJ註解驅動的切面
3純POJO切面
4注入式ASPECTJ切面
Spring藉助AspectJ的切點表達式語言來定義Spring切面
arg() 限制鏈接點匹配參數爲指定類型的執行方法
@args() 限制鏈接點匹配參數由指定註解標註的執行方法
execution()用於匹配是鏈接點的執行方法
this()限制鏈接點匹配AOP代理的bean引用爲指定類型的類
target()限制鏈接點匹配目標對象爲指定類型的類
@target()限制鏈接點匹配特定的執行對象,這些對象對應的類要具有指定類型的註解
within()限制鏈接點匹配指定的類型
@within()限制鏈接點匹配指定註解所標註的類型(當使用spring AOP時,方法定義在由指定的註解所標註的類裏)
@annotation 限制匹配帶有指定註解鏈接點
================================
execution( * <!--返回任意類型--> com.a.b.c.method(..)) 後面表示任意參數
表示觸發條件!
---
execution( * <!--返回任意類型--> com.a.b.c.method(..)) 後面表示任意參數
&& within(a.b.c.*)這個是指包下面的任意類的方法被調用時
||表示或,!表示非
若是加上and bean(beanId)則表示必須是這個bean上執行。
!bean(id)不解釋
---
<aop:advisor> 定義AOP通知器
<aop:after>定義AOP後置通知(無論被通知的方法是否執行成功)
<aop:after-returning>定義AOP after-returning通知
<aop:after-throwing>定義after-throwing通知
<aop:around>定義AOP環繞通知
<aop:aspect>定義切面
<aop:aspectj-autoproxy>啓動@AspectJ註解驅動的切面
<aop:before>定義AOP前置通知
<aop:config>頂層的AOP配置元素,大多數的<aop:*>元素必須包含在<aop:config>元素內
<aop:declare-parents>爲被通知的對象引入額外的接口,並透明的實現
<aop:pointcut>定義切點
----------------------------------------
package com.springinaction.springidol;
public class Audience {
public void takeSeats(){
System.out.println("The audience is taking their seats.");
}
public void turnOffCellPhones(){
System.out.println("The audience is turning off their cellphones.");
}
public void applaud(){
System.out.println("CLAP CLAP CLAP");
}
public void demandRefund(){
System.out.println("Boo! we want our money back!");
}
}
對應的XML文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="audience" class="com.springinaction.springidol.Audience" />
<aop:config>
<aop:aspect ref="audience">
<aop:before pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="takeSeats" />
<aop:before pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="turnOffCellPhones" />
<aop:after-returning pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="applaud" />
<aop:after-throwing pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="demandRefund" />
</aop:aspect>
</aop:config>
</beans>
或者這麼寫
<aop:config>
<aop:aspect ref="audience">
<aop:pointcut id="performance" expression="execution(* com.springinaction.springidol.Performer.perform(..))"/>
<aop:before pointcut-ref="performance" method="takeSeats" />
<aop:before pointcut-ref="performance" method="turnOffCellPhones" />
<aop:after-returning pointcut-ref="performance" method="applaud" />
<aop:after-throwing pointcut-ref="performance" method="demandRefund" />
</aop:aspect>
</aop:config>
----------------------如下爲真實可運行版本
package com.springinaction.springidol;
public class Audience {
public void takeSeats(){
System.out.println("The audience is taking their seats.");
}
public void turnOffCellPhones(){
System.out.println("The audience is turning off their cellphones.");
}
public void applaud(){
System.out.println("CLAP CLAP CLAP");
}
public void demandRefund(){
System.out.println("Boo! we want our money back!");
}
}
package com.springinaction.springidol;
public class Performer {
public void perform(){
System.out.println("actors perform...");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="performer" class="com.springinaction.springidol.Performer" />
<bean id="audience" class="com.springinaction.springidol.Audience" />
<aop:config>
<aop:aspect ref="audience">
<aop:before pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="takeSeats" />
<aop:before pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="turnOffCellPhones" />
<aop:after-returning pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="applaud" />
<aop:after-throwing pointcut="execution(* com.springinaction.springidol.Performer.perform(..))"
method="demandRefund" />
</aop:aspect>
</aop:config>
</beans>
package com.springinaction.springidol;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args){
ApplicationContext appContext = new ClassPathXmlApplicationContext("t.xml");
Performer p= appContext.getBean("performer", Performer.class);
p.perform();
}
}