public class Cat { private String name; public void eat(String food){ System.out.println(name+"喜歡吃"+food); } public int division(int a,int b){ int c=a/b; return c; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
2.書寫配置文件java
<?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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--建立代理目標,誰將被代理--> <bean id="cat" class="com.lining.springproxy.Cat"> <property name="name" value="湯姆"/> </bean> <!-- 肯定須要 添加的代碼所在的 bean--> <bean id="advices" class="com.lining.springproxy.CatAdivices"/> <aop:config> <!--定義切面--> <!--能夠經過ref來肯定引入代碼的位置的bean--> <aop:aspect ref="advices"> <!-- 經過 aop:pointcut 來聲明一個【切點】 ( 這個切點在 aop:aspect 內部,因此是局部切點 ) --> <!--該標籤中的expresion是經常使用切點函數,是爲了指定處理函數,--> <!--execution(....)參數爲:修飾符,返回類型.方法名(參數),異常,指定哪個類的哪個方法爲切點--> <!--在多個表達式之間使用 ||,or表示 或,使用 &&,and表示 與,!表示 非.--> <!-- 在 包名中使用 .. 表示 多層路徑 --> <!-- 在 () 以前中使用 * 表示 某個類中的全部方法 --> <!-- 在 參數列表中使用 .. 表示 任意多個參數 ( 能夠是 零個、一個、多個) --> <!-- 在 參數列表中使用 * 表示 至少有一個參數 ( 能夠是 一個 或 多個) --> <aop:pointcut id="first" expression="execution(* com.lining.springproxy.Cat.*(..))"/> <!-- 在 firstPointcut 所選擇 【鏈接點】( 指定的 執行點 執行以前 ) 處 加入prompter中的 before 方法 對應的代碼 --> <!-- 在 firstPointcut 所選擇的那些方法以前前 先執行 prompter 對象 before 方法--> <aop:before method="before" pointcut-ref="first" /> <aop:after-throwing method="exe" pointcut-ref="first" /> <aop:around method="round" pointcut-ref="first" /> <aop:after-returning method="areturn" pointcut-ref="first" /> <aop:after method="after" pointcut-ref="first" /> </aop:aspect> </aop:config> </beans>
package com.lining.springproxy; import org.aspectj.lang.ProceedingJoinPoint; public class CatAdivices { public void before(){ System.out.println("我是before"); } public void exe(){ System.out.println("我是異常exeception"); } public void areturn(){ System.out.println("我是return"); } public Object round(ProceedingJoinPoint joinPoint ) throws Throwable{ System.out.println("我圍繞在上面"); Object s=joinPoint.proceed(); System.out.println("我圍繞在下面"); return s; } public void after(){ System.out.println("我是after"); } }
4.書寫測試類spring
public class CatTest { public static void main(String[] args) { AbstractApplicationContext context=new ClassPathXmlApplicationContext("com/lining/AOPproxy.xml"); Object proxy= context.getBean("cat"); if(proxy instanceof Cat){ Cat s=(Cat)proxy; s.eat("小龍蝦"); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); s.division(6,0); } context.close(); } }
我是before 我圍繞在上面 湯姆喜歡吃小龍蝦 我是after 我是return 我圍繞在下面 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 我是before 我圍繞在上面 我是after 我是異常exeception Exception in thread "main" java.lang.ArithmeticException: / by zero
以上即是具體的實現過程,其中主要用到了動態代理的思想,在每個方位上添加代碼,這樣能夠減小之後項目維護時的複雜程度。咱們也能夠用標籤的方式來書寫AOP,可是做爲初學者仍是先弄懂配置文件的書寫過程在學習Sping時,咱們也能夠用原生的jdk來書寫動態代理實現AOP.這些方法咱們將在下一篇中講到。 ** 要先學會代理否則你是看不懂這些的**express