1 通知所有方法的实现
前面的例子中通过 ProxyFactory.setAdvice()方法为代理设置通知,该方法在后台委托给 addVisor() ,该方法会创建一个DefaultPointcutAdvisor实例,并将切入点设为“所有方法调用”。实现代码如下:
Org.springframework.aop.framework.AdvisedSupport.java
public void addAdvice(Advice advice) throws AopConfigException {
int pos = this.advisors.size();
addAdvice(pos, advice);
}
public void addAdvice(int pos, Advice advice) throws AopConfigException {
Assert.notNull(advice, "Advice must not be null");
if (advice instanceof IntroductionInfo) {
// We don't need an IntroductionAdvisor for this kind of introduction:
// It's fully self-describing.
addAdvisor(pos, new DefaultIntroductionAdvisor(advice, (IntroductionInfo) advice));
}
else if (advice instanceof DynamicIntroductionAdvice) {
// We need an IntroductionAdvisor for this kind of introduction.
throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor");
}
else {
addAdvisor(pos, new DefaultPointcutAdvisor(advice));
}
}
2 通知指定方法的实现
通过切入点,控制应该通知的类和方法。
2.1 Spring 中的通知者
通知者 Advisor | 切入点 Pointcut(指定切入的类与方法) | MyStaticPoincut.java |
通知 Advice(增加通知的逻辑) | MyAdvice.java |
2.2 示例代码
package cuigh.spring.aop.step02;
/*
* 功能;演示对指定类,指定方法进行通知
* */
public class Math1 {
/*
* 功能:演示对此方法的 不 通知
* */
public int add(int a,int b){
int c=a+b;
System.out.println("Math1.add()方法:"+a+"+"+b+"="+c);
return c;
}
/*
* 功能:演示对此方法的通知
* */
public int sub(int a,int b){
int c=a-b;
System.out.println("Math1.sub()方法:"+a+"-"+b+"="+c);
return c;
}
}
package cuigh.spring.aop.step02;
/*
* 功能;演示对指定类,指定方法进行通知
* */
public class Math2 {
/*
* 功能:演示对此方法的通知
* */
public int add(int a,int b){
int c=a+b;
System.out.println("Math2.add()方法:"+a+"+"+b+"="+c);
return c;
}
/*
* 功能:演示对此方法的 不 通知
* */
public int sub(int a,int b){
int c=a-b;
System.out.println("Math2.sub()方法:"+a+"-"+b+"="+c);
return c;
}
}
package cuigh.spring.aop.step02;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/*
* 功能:增加通知逻辑
*
* */
public class MyAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("通知的方法为:"+arg0.getClass()+"."+arg0.getMethod().getName());
Object retVal = arg0.proceed();
System.out.println("被通知方法执行结束");
return retVal ;
}
}
package cuigh.spring.aop.step02;
import java.lang.reflect.Method;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
/*
* 功能:演示 对 Math1.sub() 与 Math2.add()方法的通知
* */
public class MyStaticPoincut extends StaticMethodMatcherPointcut {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return ( ("sub".equals(method.getName()) && (targetClass==Math1.class))
|| ("add".equals(method.getName()) && (targetClass==Math2.class))
);
}
}
package cuigh.spring.aop.step02;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
/**
* 功能:演示spring静态方法匹配器切入点使用
*/
public class AdvisorStaticExample {
public static void main(String[] args) {
//创建目标对象
Math1 math1 = new Math1();
Math2 math2 = new Math2();
Math1 math1Proxy;
Math2 math2Proxy;
int a=10,b=2;
//创建切入点
Pointcut pointcut = new MyStaticPoincut();
//创建通知
Advice advice = new MyAdvice();
//创建通知者
Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice);
//创建目标对象 math1 的代理
ProxyFactory pf = new ProxyFactory();
//设置通知者
pf.addAdvisor(advisor);
//设置目标对象
pf.setTarget(math1);
math1Proxy = (Math1)pf.getProxy();
math1Proxy.add(a, b);
math1Proxy.sub(a, b);
System.out.println("------------------------------");
//创建目标对象 math12的代理
pf = new ProxyFactory();
//设置目标对象
pf.setTarget(math2);
//设置通知者
pf.addAdvisor(advisor);
math2Proxy = (Math2)pf.getProxy();
math2Proxy.add(a, b);
math2Proxy.sub(a, b);
}
}
程序输出:
Math1.add()方法:10+2=12
通知的方法为:class org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.sub
Math1.sub()方法:10-2=8
被通知方法执行结束
------------------------------
通知的方法为:class org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.add
Math2.add()方法:10+2=12
被通知方法执行结束
Math2.sub()方法:10-2=8