1.要利用spring aop,至少須要添加如下jar包java
使用spring須要的jar
spring.jar 、commons-logging.jarnode
使用切面編程(AOP)須要的jarspring
aspectjrt.jar、aspectjweaver.jar、cglib-nodep-2.1_3.jar編程
使用JSR-250提供的註解,如@Resource,須要的jaride
common-annotations.jar單元測試
2.使用spring 進行aop編程,首先咱們要在Spring的配置文件中引入aop命名空間:測試
1 <beans xmlns=http://www.springframework.org/schema/beans 2 xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance 3 xmlns:aop=http://www.springframework.org/schema/aop 4 xsi:schemaLocation=」http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 6 http://www.springramework.org/schema/aop 7 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd」> 8 9 </beans>
固然咱們在使用spring的時候,確定會使用到spring ioc相關的內容,也須要加入命名空間對IOC部分的支持spa
3.使用註解方式來實現aop,首先須要在spring的配置文件中啓動對@AspectJ註解的支持
code
<aop:aspectj-autoproxy/>xml
4.創建一個類,做爲切面類,而後在切面類中依次添加切入點,前置通知,後置通知,例外通知,最終通知,環繞通知等:
完整的java文件:
1 package com.yangyang.aop; 2 3 import org.aspectj.lang.ProceedingJoinPoint; 4 import org.aspectj.lang.annotation.After; 5 import org.aspectj.lang.annotation.AfterReturning; 6 import org.aspectj.lang.annotation.AfterThrowing; 7 import org.aspectj.lang.annotation.Around; 8 import org.aspectj.lang.annotation.Aspect; 9 import org.aspectj.lang.annotation.Before; 10 import org.aspectj.lang.annotation.Pointcut; 11 12 //聲明該類爲一個切面 13 @Aspect 14 public class MyInterceptor { 15 //切入點要攔截的類 16 @Pointcut("execution (* com.yangyang.service..*.*(..))") 17 private void anyMethod(){} //聲明一個切入點,切入點的名稱實際上是一個方法 18 19 //前置通知(不須要獲取輸入參數) 20 @Before("anyMethod()")//第一個參數爲切入點的名稱 21 public void doAccessCheck(){ 22 System.out.println("前置通知"); 23 } 24 25 //後置通知(不須要獲取返回值) 26 @AfterReturning("anyMethod()") 27 public void doAfterReturning(){ 28 System.out.println("後置通知:"); 29 } 30 31 //例外通知(不須要異常信息) 32 @AfterThrowing("anyMethod()") 33 public void doAfterThrowing(){ 34 System.out.println("例外通知"); 35 } 36 37 //最終通知 38 @After("anyMethod()") 39 public void doAfter(){ 40 System.out.println("最終通知"); 41 } 42 43 //環繞通知(特別適合作權限系統) 44 @Around("anyMethod()") 45 public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{ 46 System.out.println("環繞通知進入方法"); 47 Object object=pjp.proceed(); 48 System.out.println("環繞通知退出方法"); 49 return object; 50 } 51 52 }
5.創建供測試的業務方法:這裏只列出實現:
1 package com.yangyang.service.impl; 2 3 import com.yangyang.service.PersonService; 4 5 public class PersonServiceImpl implements PersonService{ 6 7 @Override 8 public String getNameById(Long id) { 9 System.out.println("我是getNameById()方法"); 10 return "csy"; 11 } 12 13 @Override 14 public void save(String name) { 15 throw new RuntimeException("故意拋出了異常,僅供測試"); 16 // System.out.println("我是save()方法"); 17 } 18 19 @Override 20 public void update(String name, Long id) { 21 System.out.println("我是update()方法"); 22 } 23 24 }
6.將業務service的bean以及切面的類加入spring管理,完整的配置文件以下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 8 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 9 <!-- 加上aop的命名空間以及DTD驗證 --> 10 11 12 <aop:aspectj-autoproxy/><!-- 打開aop對@Aspectj的註解支持 ,至關於爲註解提供解析功能--> 13 14 <bean id="myInterceptor" class="com.yangyang.aop.MyInterceptor"></bean> 15 16 <bean id="personService" class="com.yangyang.service.impl.PersonServiceImpl"> 17 </bean> 18 19 </beans>
7.編寫單元測試,來測試aop是否成功實現。代碼:
1 @Test 2 public void testSpringInterceptor() { 3 ApplicationContext ctx=new ClassPathXmlApplicationContext("resources/beans.xml"); 4 PersonService personService=(PersonService)ctx.getBean("personService"); 5 personService.getNameById(1l); 6 System.out.println("----------------------------------"); 7 personService.save("csy"); 8 }
觀察結果以下:
前置通知
環繞通知進入方法
我是getNameById()方法
後置通知:
最終通知
環繞通知退出方法
----------------------------------
前置通知
環繞通知進入方法
例外通知
最終通知
能夠看出AOP編寫成功了。
思考一個問題,若是咱們但願獲取在業務操做在使用aop的服務時獲得相應的輸入,返回值,以及異常信息,那麼切面該怎麼改呢:
只須要在各自通知的地方加入相應類型的參數便可:
1 package com.yangyang.aop; 2 3 import org.aspectj.lang.ProceedingJoinPoint; 4 import org.aspectj.lang.annotation.After; 5 import org.aspectj.lang.annotation.AfterReturning; 6 import org.aspectj.lang.annotation.AfterThrowing; 7 import org.aspectj.lang.annotation.Around; 8 import org.aspectj.lang.annotation.Aspect; 9 import org.aspectj.lang.annotation.Before; 10 import org.aspectj.lang.annotation.Pointcut; 11 12 //聲明該類爲一個切面 13 @Aspect 14 public class MyInterceptor { 15 //切入點要攔截的類 16 @Pointcut("execution (* com.yangyang.service..*.*(..))") 17 private void anyMethod(){} //聲明一個切入點,切入點的名稱實際上是一個方法 18 19 //前置通知(獲取輸入參數) 20 @Before("anyMethod() && args(name)")//第一個參數爲切入點的名稱,第二個是測試獲取輸入參數,此處爲string類型的,參數名稱與方法中的名稱相同,若是不獲取輸入參數,能夠不要 21 public void doAccessCheck(String name){ 22 System.out.println("前置通知:"+name); 23 } 24 25 //後置通知(獲取返回值) 26 @AfterReturning (pointcut="anyMethod()", returning="result") 27 public void doAfterReturning(String result){ 28 System.out.println("後置通知:"+result); 29 } 30 31 //例外通知(獲取異常信息) 32 @AfterThrowing(pointcut="anyMethod()",throwing="e") 33 public void doAfterThrowing(Exception e){ 34 System.out.println("例外通知:"+e); 35 } 36 37 //最終通知 38 @After("anyMethod()") 39 public void doAfter(){ 40 System.out.println("最終通知"); 41 } 42 43 //環繞通知(特別適合作權限系統) 44 @Around("anyMethod()") 45 public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{ 46 System.out.println("環繞通知進入方法"); 47 Object object=pjp.proceed(); 48 System.out.println("環繞通知退出方法"); 49 return object; 50 } 51 52 }
同理執行單元測試,能夠看到結果:
環繞通知進入方法
我是getNameById()方法
後置通知:csy
最終通知
環繞通知退出方法
----------------------------------
前置通知:csy
環繞通知進入方法
例外通知:java.lang.RuntimeException: 故意拋出了異常,僅供測試
最終通知
這樣咱們的功能就開發完了