java拦截器Interceptor
1.java 拦截器原理
拦截器本质:利用反射和动态代理两个知识点。通过反射获取类本身的方法。通过动态代理,动态的获取方法,另在方法的前后添加其他的逻辑处理。
2.代码演示
1 实体类接口
public interface BusinessFacade {
public void doSomething();
}
2 实体类
public class BusinessClass implements BusinessFacade {
public void doSomething() {
System.out.println("在业务组件 BusinessClass 中调用方法: doSomething()");
}
}
3 拦截器
public class InterceptorClass {
// 在 action 之前调用
public void before(){
System.out.println("在拦截器 InterceptorClass 中调用方法: before()");
}
// 在 action 之后调用
public void after(){
System.out.println("在拦截器 InterceptorClass 中调用方法: after()");
}
}
4 代理类
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;
import java.lang.reflect.Method;
/**
* 动态代理处理器工具
*/
public class DynamicProxyHandler implements InvocationHandler {
// 声明被代理对象
private Object business;
// 创建拦截器
private InterceptorClass interceptor = new InterceptorClass();
/**
* 动态生成一个代理类对象,并绑定被代理类和代理处理器。
* @return 代理类对象
*/
public Object bind(Object business) {
this.business = business;
/**
* Proxy.newProxyInstance(参数1, 参数2, 参数3)
*
* 参数1, 表示被代理类的 ClassLoader
* 参数2, 表示被代理的接口
* 参数3, 表示代理处理器对象
*
* 该方法,返回代理实例
*/
return Proxy.newProxyInstance(business.getClass().getClassLoader(),
business.getClass().getInterfaces(),
this);
}
/**
* 代理需要调用的方法,并在该方法调用前后,先调用连接器的方法。
*
* @param proxy 代理类对象
* @param method 被代理的接口方法
* @param args 被代理接口方法的参数
* @return 方法调用返回的结果
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
interceptor.before();
result = method.invoke(business, args);
interceptor.after();
return null;
}
}
5 客户端 client
public class ClientDemo {
public static void main(String args[]) {
// 创建动态代理处理工具
DynamicProxyHandler handler = new DynamicProxyHandler();
// 创建业务组件对象
BusinessFacade business = new BusinessClass();
// 创建业务组件对象,并用动态代理绑定代理类
BusinessFacade businessProxy = (BusinessFacade) handler.bind(business);
// 调用业务组件中的方法,演示拦截器效果
businessProxy.doSomething();
}
}
输出结果:
在拦截器 InterceptorClass 中调用方法: before()
在业务组件 BusinessClass 中调用方法: doSomething()
在拦截器 InterceptorClass 中调用方法: after()