在前面四個例子中
假如我們不想通過代理來執行某些方法
Spring提供一系列接口來實現這個目標
implements org
org
org
下面看看幾個關鍵接口的定義
/**
* 切入點
*/
public interface Pointcut {
//切入點的一個單例
public static final Pointcut TRUE = TruePointcut
//類過濾器
public ClassFilter getClassFilter();
//方法過濾器
public MethodMatcher getMethodMatcher();
}
/**
* 類過濾器
*/
public interface ClassFilter {
//類過濾器單例
public static final ClassFilter TRUE = TrueClassFilter
//類匹配方法
public boolean matches(Class class
}
/**
* 方法過濾器
*/
public interface MethodMatcher {
//方法過濾器單例
public static final MethodMatcher TRUE = TrueMethodMatcher
//靜態方法匹配方法
public boolean matches(Method method
//判斷靜態還是動態匹配
public boolean isRuntime();
//對象(動態)匹配方法
public boolean matches(Method method
}
/**
* 通知者接口
*/
public interface Advisor {
//切面是否為per instance
public boolean isPerInstance();
//獲取切面上的通知
public Advice getAdvice();
}
/**
* 通知者子接口
*/
public PointcutAdvisor extends Advisor {
//獲取通知者的切點
public Pointcut getPointcut();
}
為了看的明白
還有很多接口和類沒有畫出
在org
DynamicMethodMatcherPointcut
NameMatchMethodPointcut
Perl
StaticMethodMatcherPointcut
JdkRegexpMethodPointcut
ControlFlowPointcut
ComposablePointcut
與這些切點對應
通過上面的原理圖
下面給個例子看看Spring如何通過切點來選取類和方法的
例子
/**
* 業務組件
*/
public class BeanOne {
public void foo() {
System
}
public void bar() {
System
}
}
/**
* 業務組件
*/
public class BeanTwo {
public void foo() {
System
}
public void bar() {
System
}
}
import org
import org
/**
* 自定義通知
*/
public class SimpleAdvice implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System
Object retVal = invocation
System
return retVal;
}
}
import java
import org
import org
/**
* 自定義靜態切入點
*/
public class SimpleStaticPointcut extends StaticMethodMatcherPointcut {
public boolean matches(Method method
//類方法名為foo時候匹配
System
return (
}
public ClassFilter getClassFilter() {
return new ClassFilter() {
public boolean matches(Class cls) {
System
//BeanOne類匹配
return (cls == BeanOne
}
};
}
}
import org
import org
import org
import org
import org
/**
* 客戶端測試
*/
public class StaticPointcutExample {
public static void main(String[] args) {
//創建目標對象
BeanOne one = new BeanOne();
BeanTwo two = new BeanTwo();
//定義代理對象
BeanOne proxyOne;
BeanTwo proxyTwo;
//創建一個切入點
Pointcut pc = new SimpleStaticPointcut();
//創建一個通知
Advice advice = new SimpleAdvice();
//創建一個通知者(即通知和切入點的結合)
Advisor advisor = new DefaultPointcutAdvisor(pc
//創建一個代理工廠
ProxyFactory pf = new ProxyFactory();
//將方面加入工廠
pf
//將目標加入工廠
pf
//獲取代理對象產品
proxyOne = (BeanOne) pf
//創建一個代理工廠
pf = new ProxyFactory();
pf
pf
proxyTwo = (BeanTwo) pf
/*
org
設置的代理目標一次僅能一個
*/
//從代理產品上調用目標方法
proxyOne
proxyTwo
proxyOne
proxyTwo
}
}
運行結果
切入點類匹配
切入點方法匹配
切入點類匹配
切入點方法匹配
切入點類匹配
切入點方法匹配
切入點類匹配
切入點方法匹配
切入點類匹配
切入點類匹配
切入點類匹配
切入點類匹配
切入點類匹配
切入點方法匹配
>> 業務方法調用前動作
BeanOne的foo()被調用!
>> 業務方法調用結束後動作!
BeanTwo的foo()被調用!
BeanOne的bar()被調用!
BeanTwo的bar()被調用!
Process finished with exit code
From:http://tw.wingwit.com/Article/program/Java/ky/201311/11164.html