Spring AOP本質(7)
上一個裏面,給出靜態方法切點匹配的例子,如今給出一個動態的實現例子:
沒有
/**
* 業務組件
*/
public
class SampleBean {
public
void foo(
int x) {
System.out.println(
"SampleBean的foo(int x)方法被調用,參數x=" +x);
}
public
void bar() {
System.out.println(
"SampleBean的無參bar()方法被調用!");
}
}
import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.DynamicMethodMatcherPointcut;
/**
* 自定義動態切入點:Pointcut
*/
public
class SimpleDynamicPointcut
extends DynamicMethodMatcherPointcut {
/**
* 重寫了靜態方法匹配器
*/
public
boolean matches(Method method, Class cls) {
System.out.println(
"SimpleDynamicPointcut:靜態方法匹配器正在嘗試匹配方法:" + method.getName());
//僅當方法名爲foo時候才匹配
return (
"foo".equals(method.getName()));
}
/**
* 實現了動態方法匹配器
*/
public
boolean matches(Method method, Class cls, Object[] args) {
System.out.println(
"SimpleDynamicPointcut:動態方法匹配器正在嘗試匹配方法:" + method.getName());
int x = ((Integer) args[0]).intValue();
//僅當方法參數爲不等於100才匹配
return (x != 100);
}
/**
* 重寫了類匹配器
*/
public ClassFilter getClassFilter() {
return
new ClassFilter() {
public
boolean matches(Class cls) {
System.out.println(
"SimpleDynamicPointcut:切入點類匹配,正在匹配"+cls.getName()+
"類!");
return (cls == SampleBean.
class);
}
};
}
}
/**
* 自定義通知:Advice
*/
public
class SimpleAdvice
implements MethodInterceptor {
public Object invoke(MethodInvocation invocation)
throws Throwable {
System.out.println(
">> 業務方法調用前動做,被代理調用目標方法是: " + invocation.getMethod().getName());
Object retVal = invocation.proceed();
System.out.println(
">> 業務方法調用結束後動做!");
return retVal;
}
}
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import com.apress.prospring.ch6.staticpc.SimpleAdvice;
/**
* 動態方法匹配器切入點:客戶端測試
*/
public
class DynamicPointcutExample {
public
static
void main(String[] args) {
//建立目標對象
SampleBean target =
new SampleBean();
// 建立通知者
Advisor advisor =
new DefaultPointcutAdvisor(
new SimpleDynamicPointcut(),
new SimpleAdvice());
//建立代理工廠
ProxyFactory pf =
new ProxyFactory();
//將目標加入工廠
pf.setTarget(target);
//建立通知者
pf.addAdvisor(advisor);
//獲取代理實例(產品)
SampleBean proxy = (SampleBean)pf.getProxy();
//調用代理方法,注意參數的變化
proxy.foo(1);
proxy.foo(10);
proxy.foo(100);
proxy.bar();
proxy.bar();
proxy.bar();
}
}
運行結果:
- Using JDK 1.4 collections
SimpleDynamicPointcut:切入點類匹配,正在匹配com.apress.prospring.ch6.dynamicpc.SampleBean類!
SimpleDynamicPointcut:靜態方法匹配器正在嘗試匹配方法:foo
SimpleDynamicPointcut:切入點類匹配,正在匹配com.apress.prospring.ch6.dynamicpc.SampleBean類!
SimpleDynamicPointcut:靜態方法匹配器正在嘗試匹配方法:bar
SimpleDynamicPointcut:切入點類匹配,正在匹配com.apress.prospring.ch6.dynamicpc.SampleBean類!
SimpleDynamicPointcut:靜態方法匹配器正在嘗試匹配方法:hashCode
SimpleDynamicPointcut:切入點類匹配,正在匹配com.apress.prospring.ch6.dynamicpc.SampleBean類!
SimpleDynamicPointcut:靜態方法匹配器正在嘗試匹配方法:toString
SimpleDynamicPointcut:切入點類匹配,正在匹配com.apress.prospring.ch6.dynamicpc.SampleBean類!
SimpleDynamicPointcut:靜態方法匹配器正在嘗試匹配方法:foo
SimpleDynamicPointcut:動態方法匹配器正在嘗試匹配方法:foo
>> 業務方法調用前動做,被代理調用目標方法是: foo
SampleBean的foo(
int x)方法被調用,參數x=1
>> 業務方法調用結束後動做!
SimpleDynamicPointcut:動態方法匹配器正在嘗試匹配方法:foo
>> 業務方法調用前動做,被代理調用目標方法是: foo
SampleBean的foo(
int x)方法被調用,參數x=10
>> 業務方法調用結束後動做!
SimpleDynamicPointcut:動態方法匹配器正在嘗試匹配方法:foo
SampleBean的foo(
int x)方法被調用,參數x=100 SampleBean的無參bar()方法被調用! SampleBean的無參bar()方法被調用! SampleBean的無參bar()方法被調用! Process finished with exit code 0