面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
怎么算是面向切面?在不改变原代码的情况下嵌入一块其他的代码块儿。
水平有限也解释不太好。还是举例说明。
原来我们有一个接口
public interface StudentInfoService {
void findInfo(String studentName);
}
public class StudentInfoServiceImpl implements StudentInfoService {
@Override
public void findInfo(String studentName) {
System.out.println("你目前输入的名字是:"+studentName);
}
}
普通调用方法,则是
StudentInfoService service = new StudentInfoServiceImpl();//或者我们使用spring注入了一个实例
service.findInfo("hello world");
下面我们有一段代码要加入到这个方法前后,但是我们又不想修改findInfo里的代码,在执行方法时执行后加入的代码块。
那么下面就用到了AOP切面编程。
在Spring中aop:config中可以简单的通过配置加入一些代码块。但这里不是我们主要讨论的。
我们下面是讲如何通过代码来实现。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyHandler implements InvocationHandler{ //InvocationHandler这个是一定要实现的接口
private Object proxyObj;
public Object bind(Object obj){ //获取代理对象
this.proxyObj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();//方法之前
Object result=method.invoke(proxyObj,args); //这里是执行接口方法findInfo
after();//方法之后
return result;
}
public void before() {
System.out.println("-----before-----");
}
public void after() {
System.out.println("-----end-----");
}
}
public class OperaterHander extends MyHandler{
public void before() {//重写父类的方法
System.out.println("-----OperaterHander before-----");
}
public void after() {
System.out.println("-----OperaterHander end-----");
}
}
public class ProxyTest {
public static void main(String[] args) {
OperaterHander handler = new OperaterHander();
StudentInfoService service = (StudentInfoService) handler.bind(new StudentInfoServiceImpl());
service.findInfo("hello word");
}
}
查看结果
如此,我们可以不用修改原方法,就可以在方法前后加入自己想要加入的操作。
例如方法前后加日志,还能实现很好的业务方法隔离。
我想这就是AOP吧。