SpringAOP中的aop:config標簽


我們使用Spring的AOP功能的時候發現,我們使用普通的配置方式的時候,我們無法精確的確定將切面類中的哪個方法切入到哪個切入點上,

所以我們可以使用aop的專用標簽來完成相關的配置.其中主要表現是使用AspectJ的expression的操作

aop:config標簽
使用aop的專用標簽來完成相關的配置.其中主要表現是使用AspectJ的expression的操作:
      修改模式        類型     說明式        名稱模式(參數模式)
execution(modifiers-pattern ret-type-pattern declaring-type-pattern name-pattern(param-pattern)
    拋出模式
throws-pattern)除了返回類型模式,名字模式和參數模式以外,所有的部分都是可選的。
返回類型模式決定了方法的返回類型必須依次匹配一個連接點。

你會使用的最頻繁的返回類型模式是 *,它代表了匹配任意的返回類型。

一個全稱限定的類型名將只會匹配返回給定類型的方法。

名字模式匹配的是方法名。 你可以使用 * 通配符作為所有或者部分命名模式。

參數模式稍微有點復雜:() 匹配了一個不接受任何參數的方法, 而 (..) 匹配了一個接受任意數量參數的方法(零或者更多)。

模式 (*) 匹配了一個接受一個任何類型的參數的方法。
模式 (*,String) 匹配了一個接受兩個參數的方法,第一個可以是任意類型,第二個則必須是String類型

注意在使用之前需要在xml文件的beans標簽中加入新的schame文件:並在Eclipse中進行關聯配置

<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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

下面給出一些常見切入點表達式的例子。
1)任意包下的任意類中的公共方法的執行:
execution(public * *(..))
2)任何一個以“set”開始的方法的執行:
execution(* set*(..))
3)AccountService 接口的任意方法的執行:
execution(* com.briup.service.AccountService.*(..))
4)定義在service包里的任意方法的執行:
execution(* com.briup.service.*.*(..))
5)定義在service包以及子包里的任意方法的執行:
execution(* com.briup.service..*.*(..))

execution(* com.briup.service..*.*(..)) or execution(* com.briup.dao..*.*(..))

注意:
1.從spring容器中拿代理對象的時候也是要用目標對象的名字來拿。
2.沒有實現任何接口的目標對象也能產生代理對象。

<!-- 配置aop的代理 -->
<!--注意:<aop:config proxy-target-class="true"> 如果這樣配置則是強制使用CGLIB方式進行代理-->
<aop:config>
<!-- 定義一個切入點 並給切入點起名為myPointCut -->
<!-- 切入點是一組連接點的集合 -->
<aop:pointcut expression="execution(public * com.briup.aop.service.*.*(..))" id="myPointCut"/>

<!-- 定義哪一個advice在哪一個切入點上面起作用 -->
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="myPointCut" />
</aop:config>
<!--
expression="execution(public * com.briup.aop.service.*.*(..))"
這個引號""里面就是用表達式的方式來定義切入點,只要是符合我們這個表達式要求的
方法就是我們的連接點,連接點的集合就是我們要定義的切入點。
表達式中從左到右的*號:
第一個* 表示方法的返回類型不限。
第二個* 表示包中的任意一個類
第三個* 表示類中的任意一個方法
同時方法的參數也沒有限制.
-->

在一個切面類中定個多個方法,根據xml文件的配置每個方法都可以織入到切入點的不同位置,並且advice是在aop的標簽中進行配置,不需要再寫對應的advice類了

例如:
這個類相當於我們之前的切面類
只不過這個切面類中有很多方法都可以織入到切入點上面
我們可以控制把這里的任何一個方法織入到任何一個切入點上面

public class XmlHandler {

public void beforeTest(JoinPoint p){
System.out.println(p.getSignature().getName()+" before...");
}


public void afterTest(JoinPoint p){
System.out.println(p.getSignature().getName()+" after...");
}

public void afterReturningTest(JoinPoint p){

System.out.println(p.getSignature().getName()+" afterReturning");

}
//在和aroundAdvice結合的時候,這個方法一定要加上這個ProceedingJoinPoint類型的參數
public Object aroundTest(ProceedingJoinPoint pjp)throws Throwable{
//JoinPoint對象不能調用連接點所表示的方法 
//ProceedingJoinPoint能調用連接點所表示的方法 pjp.proceed()
System.out.println(pjp.getSignature().getName()+" is start..");
//調用到連接點方法
Object obj = pjp.proceed();
System.out.println(pjp.getSignature().getName()+" is end..");
return obj;
}

public void throwingTest(JoinPoint p,Exception ex){
System.out.println(p.getSignature().getName()+" is throwing..."+ex.getMessage());

}
}

xml文件配置:

<!-- 配置dao層對象 -->
<bean id="dao" 
class="com.briup.aop.dao.AccountDaoImpl"/>

<!-- 配置目標對象 -->
<bean name="target" class="com.briup.aop.service.AccountServiceImpl">
<property name="accountDao" ref="dao"></property>
</bean>

<!-- 配置切面類 -->
<bean name="handler" class="com.briup.aop.xml.XmlHandler"></bean>

<!-- 配置aop的代理 -->
<aop:config>

  <!-- 定義切入點名為myPointCut -->
  <aop:pointcut expression="execution(public * com.briup.aop.service.*.*(..))" id="myPointCut"/>
  
  <!-- 定義切面類 以及需要使用的advice -->   <aop:aspect id="aspect" ref="handler">     <!-- 表示beforeAdvice會把切面類handler中的beforeTest方法織入到名字叫myPointCut的切入點上面 -->     <aop:before method="beforeTest" pointcut-ref="myPointCut"/>     <!-- after表示不管方法是否正常結束都會起作用 -->     <aop:after method="afterTest" pointcut-ref="myPointCut"/>     <!-- after-returning表示方法正常結束才會起作用(拋異常時候不起作用) -->     <aop:after-returning method="afterReturningTest" pointcut-ref="myPointCut"/>     <aop:around method="aroundTest" pointcut-ref="myPointCut"/>     <!-- throwing="ex"表示throwingTest方法中接收異常對象的名字一定要是ex -->     <aop:after-throwing method="throwingTest" pointcut-ref="myPointCut" throwing="ex"/>   </aop:aspect> </aop:config>

注意:<aop:config proxy-target-class="true"> 如果這樣配置則是強制使用CGLIB方式進行代理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM