Hello
public interface Hello {
void sayHelloBefore();
void sayHelloAfter();
void sayHelloAround();
}
SayHello
public class SayHello implements Hello{
/**
*
*/
public void sayHelloBefore() {
System.out.println("say Hello before!");
}
/**
*
*/
public void sayHelloAfter() {
System.out.println("say Hello after!");
}
/**
*
*/
public void sayHelloAround() {
System.out.println("say Hello around!");
}
}
Before
public class Before {
public void invoke(JoinPoint joinPoint) {
System.out.println("Before:" + joinPoint.getSignature().getName());
}
}
After
public class After {
public void invoke(JoinPoint joinPoint) {
System.out.println("After:" + joinPoint.getSignature().getName());
}
}
Around
public class Around {
public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Around:" + joinPoint.getSignature().getName());
return joinPoint.proceed();
}
}
Introduction
public class Introduction {
public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
System.out
.println("Introduction:" + joinPoint.getSignature().getName());
return joinPoint.proceed();
}
}
Introduction 引入的作用在於是一個類在不做任何代碼修改的前提下,擁有另一套方法,或者說具備另一套本領,比如我們現在就想讓這個實現了Hello接口的SayHello類擁有Ok接口的方法
public interface Ok {
void sayOk();
}
IntroductionOk 首先要解決上述接口Ok的實現
public class IntroductionOk implements Ok {
@Override
public void sayOk() {
System.out.println("Ok!");
}
}
AllTest
public class AllTest {
private ApplicationContext app;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
app = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public final void testHello() {
Hello hello = (Hello) app.getBean("hello");
hello.sayHelloBefore();
hello.sayHelloAfter();
hello.sayHelloAround();
// 由於對Hello接口進行了引入,
// 使得實現了Hello接口的類可以具備Ok接口的功能。
// 同時,我們可以攔截這個方法讓他執行其他我們需要執行的操作
hello.sayHelloIntroduction();
((Ok) hello).sayOk();
}
}
關於表達式符號
.*+定義目標爲包下的所有類
+定義目標爲該接口的所有實現類
<?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="hello" class="org.zlex.aop.SayHello" /> <!-- after --> <bean id="after" class="org.zlex.aop.After" /> <aop:config> <aop:pointcut id="afterPoint" expression="execution(* org.zlex.aop.Hello.sayHelloAfter(..))" /> <aop:aspect id="afterAspect" ref="after"> <aop:after method="invoke" pointcut-ref="afterPoint" /> </aop:aspect> </aop:config> <!-- before --> <bean id="before" class="org.zlex.aop.Before" /> <aop:config> <aop:pointcut id="beforePoint" expression="execution(* org.zlex.aop.Hello.sayHelloBefore(..))" /> <aop:aspect id="beforeAspect" ref="before"> <aop:before method="invoke" pointcut-ref="beforePoint" /> </aop:aspect> </aop:config> <!-- around --> <bean id="around" class="org.zlex.aop.Around" /> <aop:config> <aop:pointcut id="aroundPoint" expression="execution(* org.zlex.aop.Hello.sayHelloAround(..))" /> <aop:aspect id="aroundAspect" ref="around"> <aop:around method="invoke" pointcut-ref="aroundPoint" /> </aop:aspect> </aop:config> <!-- introduction --> <!-- .*+是用於包下的,不是用於接口 +定義目標爲該接口的所有實現類 --> <bean id="introduction" class="org.zlex.aop.Introduction" /> <bean id="introductionOk" class="org.zlex.aop.IntroductionOk" /> <aop:config> <aop:aspect ref="introduction"> <aop:pointcut id="introductionPoint" expression="execution(* org.zlex.aop.Hello.sayHelloIntroduction(..))" /> <aop:declare-parents implement-interface="org.zlex.aop.Ok" types-matching="org.zlex.aop.Hello+" delegate-ref="introductionOk" /> <aop:around method="invoke" pointcut-ref="introductionPoint" /> </aop:aspect> </aop:config> </beans>
執行查看日誌:
Before:sayHelloBefore
say SayHello before!
say Hello after!
After:sayHelloAfter
Around:sayHelloAround
say Hello around!
Introduction:sayHelloIntroduction
say Hello introduction!
Ok!
仔細觀察
Before:sayHelloBefore
say Hello before!
在輸出say Hello before!前輸出Before:sayHelloBefore
say Hello after!
After:sayHelloAfter
在輸出say Hello after!後輸出After:sayHelloAfter
Around比較特殊,可以用ProceedingJoinPoint調用proceed()方法
Around:sayHelloAround
say Hello around!
Introduction:sayHelloIntroduction
say Hello introduction!
Ok!
同樣是Hello接口,在執行了sayHelloIntroduction方法時被攔截,同時輸出say Hello introduction!,此時還可以執行Ok的方法輸出
Spring Beans 結構圖如下:
如此這樣,就可以控制AOP了,當前資料少,實例也少,繼續研究!希望能做出來點實際的東西。