AOP(Aspect-OrientedProgramming,面向切面編程,好多人喜歡說面向方面編程,我以爲切面更容易解釋AOP。)java
面向切面編程,有效的下降了代碼之間的耦合性,易於維護;例如:咱們習慣在代碼中加上一些日誌信息,在程序出錯時方便快速查找找到問題,一般作法是在請求進入方法的時候打印日誌,退出前打印日誌,還有在出錯時打印日誌,那麼問題就來了,每一個方法中都須要打印日誌,這些相同的部分就能夠當作一個切面,經過配置切點來觸發所須要的功能,好比,我須要在請求進入方法的時候打印,便可使用aop當中的前置通知來作到,這樣就不須要每一個方法中都去寫一遍,配置好以後引用便可。spring
建立接口編程
package com.AspectTest.service; public interface personServer { public void save(String uname,int age); }
接口的實現app
package com.AspectTest.service; public class personServerImpl implements personServer{ @Override public void save(String uname,int age) { int a=0; age= age/a;//打開上面兩行報錯,可觸發異常通知 System.out.println("come in personServerImpl save method..."); } }
package com.AspectTest.aop; import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect//聲明這是一個切面 @Component//聲明這是一個組件,泛指...能夠去掉 public class AspectIntercepter { @Pointcut(value="execution(* com.AspectTest.service.personServerImpl.*(..))") private void pointCut(){//定義一個切入點 後面的通知直接引入切入點方法pointCut便可 personServerImpl下面的全部方法 } //環繞通知(鏈接到切入點開始執行,下一步進入前置通知,在下一步纔是執行操做方法) @Around(value="pointCut()") public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("@Around進入環繞通知..."); Object object = pjp.proceed();//執行該方法 System.out.println(pjp.getThis()+" 操做結束,退出方法;環繞[@Around]結束!..."); return object; } //前置通知(進入環繞後執行,下一步執行方法) @Before(value="pointCut()") public void doAccessCheck(JoinPoint joinPoint){ System.out.println("@Before前置通知:"+Arrays.toString(joinPoint.getArgs())); } //異常通知(出錯時執行) @AfterThrowing(value="pointCut()",throwing="ex") public void doAfterThrow(JoinPoint joinPoint,Throwable ex){ System.out.println("@AfterThrowing例外通知(異常通知)"+Arrays.toString(joinPoint.getArgs())); System.out.println("@AfterThrowing異常信息:"+ex); } //後置通知(返回以前執行) @After(value="pointCut()") public void after(){ System.out.println("@After後置通知..."); } //最終通知(正常返回通知,最後執行) @AfterReturning(value="pointCut()") public void doAfter(){ System.out.println("@AfterReturning最終通知...End!"); } }
<?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:context="http://www.springframework.org/schema/context" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 使 AspectJ 的註解起做用 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <bean id="personServiceBean" class="com.AspectTest.service.personServerImpl"/> <bean id="myInterceptor" class="com.AspectTest.aop.AspectIntercepter"/> </beans>
package com.AspectTest; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.AspectTest.service.personServer; public class SpringAopTest { @Test public void inteceptorTest(){ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-aop.xml"); personServer bean = (personServer)ctx.getBean("personServiceBean"); bean.save("badMonkey",23); // personServer p = new personServerImpl();//經過new對象是不會觸發aop的 // p.save("11", "22"); } }
@Around進入環繞通知... @Before前置通知:[badMonkey, 23] come in personServerImpl save method... com.AspectTest.service.personServerImpl@11023cad 操做結束,退出方法;環繞[@Around]結束!... @After後置通知... @AfterReturning最終通知...End!ide
@Around進入環繞通知... @Before前置通知:[badMonkey, 23] @After後置通知... @AfterThrowing例外通知(異常通知)[badMonkey, 23] @AfterThrowing異常信息:java.lang.ArithmeticException: / by zero測試
spring AOP代碼實例.net