模拟 Spring AOP 编写自己的拦截器
通过写一个简单的实例来梳理 Spring AOP 的核心原理
1.先写一个简单的接口 HelloService
public interface HelloService {
public void sayHello(String name);
}
2.接口实现类 HelloServiceImpl
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello(String name) {
if (name==null||name.trim()==""){
throw new RuntimeException("parameter is null!!");
}
System.out.println("hello :: "+name);
}
}
3.拦截器接口
// 拦截器接口
public interface Interceptor {
public boolean before(); //前置通知,事前方法
public void after(); //后置通知,事后方法
public Object around(Invocation invocation) throws Throwable; //取代原有事件方法
public void afterReturning(); //事后返回方法
public void afterThrowing(); //异常通知
boolean useAround(); //是否使用around方法取代原有方法
}
4.Invocation 对象的源代码
public class Invocation {
private Object[] params;
private Method method;
private Object target;
public Invocation(Object target, Method method,Object[] params) {
this.params = params;
this.method = method;
this.target = target;
}
// 反射方法
public Object proceed()throws InvocationTargetException,IllegalAccessException {
return method.invoke(target,params);
}
/*****getter,setter方法*****/
5.开始编写拦截器
public class MyInterceptor implements Interceptor {
@Override
public boolean before() {
System.out.println("before......");
return true;
}
@Override
public void after() {
System.out.println("after......");
}
@Override
public Object around(Invocation invocation) throws Throwable {
System.out.println("around before......");
Object obj=invocation.proceed();
System.out.println("around before......");
return null;
}
@Override
public void afterReturning() {
System.out.println("afterReturning......");
}
@Override
public void afterThrowing() {
System.out.println("afterThrowing......");
}
@Override
public boolean useAround() {
return true;
}
}
6.ProxyBean 的实现,将服务类和拦截方法织入到对应的流程,这里要理解动态代理模式
public class ProxyBean implements InvocationHandler {
private Object target=null; // 目标对象
private Interceptor interceptor=null; //拦截器
// 绑定代理对象
public static Object getProxyBean(Object target, Interceptor interceptor){
ProxyBean proxyBean = new ProxyBean();
// 保存被代理对象
proxyBean.target=target;
// 保存拦截器
proxyBean.interceptor=interceptor;
// 生成代理对象
Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),proxyBean);
// 返回代理对象
return proxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 异常标识
boolean exceptionFlag=false;
Invocation invocation = new Invocation(target, method, args);
this.interceptor.before();
Object retObj=null;
try {
if (this.interceptor.useAround()){
retObj=this.interceptor.around(invocation);
}else {
retObj=method.invoke(target,args);
}
}catch (Exception e){
// 产生异常
exceptionFlag=true;
}
this.interceptor.after();
if (exceptionFlag){
this.interceptor.afterThrowing();
}else {
this.interceptor.afterReturning();
return retObj;
}
return null;
}
}
7.测试程序
public class Demo2Application {
public static void main(String[] args) {
HelloService helloService = new HelloServiceImpl();
HelloService proxy = (HelloService) ProxyBean.getProxyBean(helloService, new MyInterceptor());
proxy.sayHello("chenjia");
System.out.println("\n############### name is null !! ################\n");
proxy.sayHello("");
}
}
小结
Spring AOP 其实就是通过我们的约定,把对应的方法通过动态代理来织入到约定的流程,这就是 Spring AOP 的核心。