Spring Aop實現




Spring Aop

實現

——

Annotation

方式(註解式)

一、spring

依賴庫



* SPRING_HOME/dist/spring.jar 


* SPRING_HOME/lib/jakarta-commons/commons-logging.jar 


* SPRING_HOME/lib/log4j/log4j-1.2.14.jar 


* SPRING_HOME/lib/


aspect


j/*.jar 


二、編寫切面


aspect




import org.aspectj.lang.annotation.Aspect; 


import org.aspectj.lang.annotation.Before; 


import org.aspectj.lang.annotation.Pointcut;

/** 
* 定義切面
* @author 
*/ 
@Aspect
public class CheckAspect { 

/** 
* 定義切入點(Pointcut),Pointcut的名稱就是allSaveMethod, 此方法不能有參數和返回值,僅是個標識。
* Pointcut的內容——"execution(*, save*(..))",是個表達式,描述哪些對象的哪些方法(訂閱Joinpoint) 

*/ 


@Pointcut("execution(* save*(..)) || execution(* del*(..))") 
private void allSaveMethod(){}; 
/* 
* 定義通知advice(before型),標識在哪個切入點(allSaveMethod),織入(weaver)此方法
*/ 


@Before("allSaveMethod()")
public void checkUser(){ 
System.out.println("=======CheckAspect.checkUser()==========="); 
}


}


軟件工程師速成系列之Spring AOP
Spring Aop的思...AOP的基本概念

測試服務類:

public class UserManagerImpl implements IUserManager {
public void delUser(int id) { 
System.out.println("=====UserManagerImpl.delUser()==========="); 


}

public String findUser(int id) { 

System.out.println("=====UserManagerImpl.findUser()==========="); 
return null; 


}


public void saveUser(String username, String password) { 
System.out.println("=====UserManagerImpl.saveUser()==========="); 


}

public void updateUser(int id) { 
System.out.println("=====UserManagerImpl.updateUser()==========="); 
}

}


三、
applicationContext.xml
中開啓aop,配置相關切面aspect類

<?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" xmlns:tx="http://www.springframework.org/schema/txxsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" > 


<!-- 啓用aop --> 
<aop:aspectj-autoproxy/>

<!--配置aspect--> 

<bean id="checkAspect" class="com.CheckAspect" />
<bean id="userManager" class="com.manager.impl.UserManagerImpl" /> 
</beans> 


四、測試用例:


public void testAspect(){ 

BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); 

IUserManager userManager = (IUserManager) factory.getBean("userManager");//生成的代理類proxy 

userManager.saveUser("cat", "123"); 

userManager.delUser(1); 
userManager.updateUser(1); 

//沒有調用切面advice,因爲方法update與之不匹配。


 





執行結果:



=======CheckAspect.checkUser()===========


=====UserManagerImpl.saveUser()=========== 


=======CheckAspect.checkUser()===========


 


=====UserManagerImpl.delUser()=========== 


=====UserManagerImpl.updateUser()=========== 


=======================================


 


Schema-based


式(


xml


配置)


 


一、類:


 


/** 





定義切面


 


* @author dell 





*/ 


public class CheckAspect { 


 


 


/* 





定義通知


advice





before


型)





標識在哪個切入點


(allSaveMethod),


織入





weaver





此方法


 


*/ 


public void checkUser(){ 


 


 


 


System.out.println("=======CheckAspect.checkUser()==========="); 


}


 


}


 


二、


applicationcontex.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





xmlns:aop="












http://www.springframework.org/schema/aop





xmlns:tx="












http://www.springframework.org/schema/tx





xsi:schemaLocation="












http://www.springframework.org/schema/beans


 












http://www.springframework.org/schema/beans/spring-beans-2.0.xsd


 


 


 


 


 


 


 


 


 


 


 


 












http://www.springframework.org/schema/aop


 












http://www.springframework.org/schema/aop/spring-aop-2.0.xsd


 


 


 


 


 


 


 


 


 


 


 


 












http://www.springframework.org/schema/tx


 












http://www.springframework.org/schema/tx/spring-tx-2.0.xsd





 


 


 


 


 


 


 


 


 


 


 


 


>


 


 


<bean id="checkAspect" class="com.CheckAspect" /> 
























<bean id="userManager" class="com.manager.impl.UserManagerImpl" />


 


<aop:config> 


 


 


 


<!-- 


配置切面


appect , ref


切面類


 


--> 


 


 


 


<aop:aspect id="check" ref="checkAspect"> 


 


 


 


 


 


 


 


<!-- 


配置切入點


pointcut, 


定義一個表達式


 


--> 


 


 


 


 


 


 


 


<aop:pointcut 


id="allSaveMethod" 


expression="execution(* 


com.manager.impl.UserManagerImpl.save*(..))"/> 


 


 


 


 


 


 


 


<!-- 


設置


before 


advice, 





checkAspect


中的一個方法,並定位到相位的切入點


pointcut --> 


 


 


 


 


 


 


 


<aop:before method="checkUser" pointcut-ref="allSaveMethod"/> 


 


 


 


</aop:aspect> 


</aop:config>


 


</beans> 


三、測試用例:


 


public void testAspect(){ 


 


 


 


BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); 


 


 


 


IUserManager userManager = (IUserManager) factory.getBean("userManager"); 


 


 


 


userManager.saveUser("cat", "123"); 


 


 


 


userManager.delUser(1); 


 


 


 


userManager.updateUser(1); 





輸出結果:


 


=======CheckAspect.checkUser()===========


 


=====UserManagerImpl.saveUser()=========== 


=====UserManagerImpl.delUser()=========== 


=====UserManagerImpl.updateUser()=========== 


四、


Advice


中可以加入


JoinPoint


參數,內含有代理類的方法的方法


名和參數數組


 


import 


org.aspectj.lang.JoinPoint





/* 





定義通知


advice





before


型)


,標識在哪個切入點


(allSaveMethod),


織入(


weaver


)此方法


 


* JoinPoint 


內含代理類的參數和方法


 


*/ 


public void checkUser(


JoinPoint joinPoint


){ 


 


 


 


Object[] args = joinPoint.getArgs(); 


 


 


 


for(int i=0; i<args.length; i++){ 


 


 


 


 


System.out.println("


參數


" + i + "=" + args[i]); 


 


 


 





 


 


 


System.out.println("


代理類的方法:


" + joinPoint.getSignature().getName()); 


 


 


 


System.out.println("=======CheckAspect.checkUser()==========="); 



























輸入結果:


 


參數


0=cat 


參數


1=123 


代理類的方法:


saveUser 


=======CheckAspect.checkUser()===========


 


=====UserManagerImpl.saveUser()=========== 


=====UserManagerImpl.delUser()=========== 


=====UserManagerImpl.updateUser()=========== 


=======================================


 


注:


Aspect


默認情況下不用實現接口,但對於目標對象(


UserManagerImpl.java





,在默認


情況下必須實現接口;


 


如果沒有實現接口必須引入


CGLIB





 


==================================


 


Spring AOP 


用戶可能會經常使用


 


execution


pointcut designator


。執行表達式的格式


如下:


 


execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) 


throws-pattern?) 


除了返回類型模式


(上面代碼片斷中的


ret-type-pattern








名字模式和參數模式以外,


所有的


部分都是可選的。


 


返回類型模式決定了方法的返回類型必須依次匹配一個連接點。


 


你會使


用的最頻繁的返回類型模式是


 


*


,它代表了匹配任意的返回類型。


 


一個全稱限定的類型名


將只會匹配返回給定類型的方法。


名字模式匹配的是方法名。


 


你可以使用


 


*


 


通配符作爲所


有或者部分命名模式。


 


參數模式稍微有點複雜:


()


 


匹配了一個不接受任何參數的方法,


 





 


(..)


 


匹配了一個接受任意數量參數的方法


(零或者更多)





 


模式


 


(*)


 


匹配了一個接受一個


任何類型的參數的方法。


 


模式


 


(*,String)


 


匹配了一個接受兩個參數的方法,第一個可以


是任意類型,


第二個則必須是


String


類型。


 


請參見


AspectJ


編程指南的


 












Language Semantics


 


部分。


 


下面給出一些常見切入點表達式的例子。


 


任意公共方法的執行:


 


execution(public * *(..)) 


任何一個以


“set”


開始的方法的執行:


 


execution(* set*(..)) 


AccountService


 


接口的任意方法的執行:


 


execution(* com.xyz.service.AccountService.*(..)) 


定義在


service


包裏的任意方法的執行:


 


execution(* com.xyz.service.*.*(..)) 


定義在


service


包或者子包裏的任意方法的執行:


 


execution(* com.xyz.service..*.*(..)) 





service


包裏的任意連接點(在


Spring AOP


中只是方法執行)


 





 


within(com.xyz.service.*) 





service


包或者子包裏的任意連接點(在


Spring AOP


中只是方法執行)


 





 


within(com.xyz.service..*) 


實現了


 


AccountService


 


接口的代理對象的任意連接點


(在


Spring AOP


中只是方法執行)


 





 


this(com.xyz.service.AccountService) 


注:來自百度文檔、內容僅供個人學習

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