接着前一章,我们根据query与check的横切图来真真正正用Java实现一遍,更有助于理解这整个AOP过程。AOP的实现应该是运用了反射机制(Java Reflection)[1],通过反射,在运行中读取编译好的类,从而获取类名、方法名,并进行一系列操作(有点类似破解的味道)
所以,AOP是不安全的!(大误)……其实类似Spring这样,把类的创建权交给别人本身,就是不太安全的。除非你真的非常信赖Spring……当然,这也是Spring和AOP为什么开源、流行的原因,大家都必须可以检查是否留有后门。这里我们假设AOP没有后门,不会给我们的query加上除了我们相加的check之外的任何函数。
在第一章我们看到的图:
还记得之前说过,Spring就是一个类工厂,按照订单需求生成Object。但是我一个手机工厂,总不能给你一台不能上网的电脑吧?所以其实这个需求也是有限定的,这个限定就是一个interface。我们虽然希望所有的query()方法都需要检查,但是还是得限定在一个Class里面
(若是AOP有更强大的功能,我们再探索,目前教程先举这个限定死的简单的例子)
文件QueryInterface.java
package aop;
public interface QueryInterface {
}
|
然后我们实现这个接口:
文件QueryClass.java
package aop;
public class QueryClass implements QueryInterface{
}
|
可以看到我们有不同的query方法。接下来是重点,我们如何AOP呢?我们使用Spring的AOP,需要引入一个额外的包,叫aopalliance.jar(
可以百度搜一下,不过别用那个aopalliance-alpha1.jar,它还不支持Spring4)。这个包提供了一系列AOP方法。加载完包之后,我们新建一个CheckClass类:
文件CheckClass.java
package aop;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
public class CheckClass implements MethodBeforeAdvice,AfterReturningAdvice{
}
|
然后,我们在Spring的配置文件里面,将整个流程都统一起来。
文件beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
</beans>
|
最后,我们在main函数里面运行代码:
文件MainClass.java
package Main;
import aop.QueryInterface;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationC
public class MainClass {
}
|
运行结果如下:
从结果我们可以看到,方法queryN由于不符合正则表达式的匹配,所以并没有运行前处理程序和后处理程序。如果我们把queryN的方法名改成query999,那么它就会被匹配,激发前后处理函数运行。
参考资料:
[1]
Java反射机制详解