缺点:对目标类中的同名不同参数和不同返回值的所有方法都进行增强
检查对象:代理类和代理类调用的方法
静态检查时间:代理对象初始化时和代理对象进行方法调用时做静态检查
静态检查方式:
先做类检查,如果类匹配成功,则进行方法检查(对于类中的所有同名的方法都能匹配成功,不管参数和返回值是否相同,都能匹配成功)。如果类匹配不成功,则不进行方法检查。(注:第二次调用同类同名同参数的函数值不进行检查)
测试:
两个目标对象类NativeWaiter和NativeSeller
package com.sias;
public class NativeWaiter{
public void greeTo(String clientName){
System.out.println("I am waiter,I am happay greeTo"+clientName);
}
public void serverTo(String clientName){
System.out.println("I am waiter,I am happay serverTo"+clientName);
}
}
package com.sias;
public class NativeSeller{
public void serverTo(String clientName){
System.out.println("I am Seller,I am happy to serverTo"+clientName);
}
}
一个前置增强类GreetBeforeAdvice类,继承了MethodBeforeAdvice接口
package com.sias;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class GreetBeforeAdvice implements MethodBeforeAdvice{
public void before(Method method,Object[] args,Object obj) throws Throwable{
String clientName=(String)args[0];
System.out.println("调用"+obj.getClass().getName()+"类的"+method.getName()+"方法");
System.out.println("How are you!"+clientName);
}
}
一个静态切面类GreetingAdvisor,该方法需要继承StaticMethodMacherPointcutAdvisor类,以实现
他的Matches(Method method,Class clazz)和getClassFilter()方法
package com.sias;
import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor{
public boolean matches(Method method,Class clazz){
System.out.println("调用静态切面类的mathes()方法对"+clazz.toString()+"类的"+method.getName()+"进行静态检查");
return "greeTo".equals(method.getName());
}
public ClassFilter getClassFilter(){
return new ClassFilter(){
public boolean matches(Class clazz){
System.out.println("调用getClassFileter()对"+clazz.getName()+"类进行静态检查");
return NativeWaiter.class.isAssignableFrom(clazz);
}
};
}
}
spring的配置文件applicationContext.xml配置文件,该文件放在war工程包下的classes文件夹中
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="waiterTarget" class="com.sias.NativeWaiter"/>
<bean id="sellerTarget" class="com.sias.NativeSeller"/>
<bean id="greetingAdvice" class="com.sias.GreetBeforeAdvice"/>
<bean id="greetingAdvisor" class="com.sias.GreetingAdvisor">
<property name="advice" ref="greetingAdvice"/>
</bean>
<bean id="parent" abstract="true" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<idref local="greetingAdvisor"/>
</property>
<property name="proxyTargetClass" value="true"/>
</bean>
<bean id="waiter" parent="parent">
<property name="target" ref="waiterTarget"/>
</bean>
<bean id="seller" parent="parent">
<property name="target" ref="sellerTarget"/>
</bean>
</beans>
下面编辑一个测试的类,我用的是jsp页面访问的形式,当然,你也可以用一个主类测试,其中主要代码如下
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
NativeWaiter n1=(NativeWaiter)ctx.getBean("waiter");
NativeSeller n2=(NativeSeller)ctx.getBean("seller");
n1.greeTo("阿丁");
n1.serverTo("阿丁");
n2.serverTo("啊迈");
运行结果如下
7:37:40,078 INFO [STDOUT] 调用getClassFileter()对com.sias.NativeWaiter类进行静态检查
17:37:40,078 INFO [STDOUT] 调用静态切面类的mathes()方法对class com.sias.NativeWaiter类的greeTo进行静态检查
17:37:40,093 INFO [STDOUT] 调用getClassFileter()对com.sias.NativeWaiter类进行静态检查
17:37:40,093 INFO [STDOUT] 调用静态切面类的mathes()方法对class com.sias.NativeWaiter类的serverTo进行静态检查
17:37:40,093 INFO [STDOUT] 调用getClassFileter()对com.sias.NativeWaiter类进行静态检查
17:37:40,093 INFO [STDOUT] 调用静态切面类的mathes()方法对class com.sias.NativeWaiter类的clone进行静态检查
17:37:40,093 INFO [STDOUT] 调用getClassFileter()对com.sias.NativeWaiter类进行静态检查
17:37:40,093 INFO [STDOUT] 调用静态切面类的mathes()方法对class com.sias.NativeWaiter类的toString进行静态检查
17:37:40,125 INFO [STDOUT] 调用getClassFileter()对com.sias.NativeSeller类进行静态检查
17:37:40,125 INFO [STDOUT] 调用getClassFileter()对com.sias.NativeSeller类进行静态检查
17:37:40,125 INFO [STDOUT] 调用getClassFileter()对com.sias.NativeSeller类进行静态检查
17:37:40,140 INFO [STDOUT] 调用getClassFileter()对com.sias.NativeWaiter类进行静态检查
17:37:40,140 INFO [STDOUT] 调用静态切面类的mathes()方法对class com.sias.NativeWaiter类的greeTo进行静态检查
17:37:40,140 INFO [STDOUT] 调用com.sias.NativeWaiter类的greeTo方法
17:37:40,140 INFO [STDOUT] How are you!阿丁
17:37:40,140 INFO [STDOUT] I am waiter,I am happay greeTo阿丁
17:37:40,140 INFO [STDOUT] 调用getClassFileter()对com.sias.NativeWaiter类进行静态检查
17:37:40,140 INFO [STDOUT] 调用静态切面类的mathes()方法对class com.sias.NativeWaiter类的serverTo进行静态检查
17:37:40,140 INFO [STDOUT] I am waiter,I am happay serverTo阿丁
17:37:40,140 INFO [STDOUT] 调用getClassFileter()对com.sias.NativeSeller类进行静态检查
17:37:40,140 INFO [STDOUT] I am Seller,I am happy to serverTo啊迈
补充说明:
MethodBeforeAdvice中的void before(Method method,Object[] args,Object obj) throws Throwable方法,如果被加强目标对象的方法为参数为空时,Object[] args并不为null,此时,为一个长度为0的对象数组。用args.length和0比较来判断是否有参数传入