Mybatis 源码之Plugin类解析
2016-01-13 20:21
369 查看
public class Plugin implements InvocationHandler { private Object target; //目标对象 private Interceptor interceptor;//拦截器对象 private Map<Class<?>, Set<Method>> signatureMap;//目标对象方法签名 private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) { this.target = target; this.interceptor = interceptor; this.signatureMap = signatureMap; } public static Object wrap(Object target, Interceptor interceptor) { //从拦截器的注解中获取拦截的类名和方法信息 Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor); Class<?> type = target.getClass(); //解析被拦截对象的所有接口 Class<?>[] interfaces = getAllInterfaces(type, signatureMap); if (interfaces.length > 0) { //生成代理对象,Plugin对象为该代理对象的InvocationHandler return Proxy.newProxyInstance( type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)); } return target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { Set<Method> methods = signatureMap.get(method.getDeclaringClass()); if (methods != null && methods.contains(method)) { //调用代理类所属拦截器的intercept方法 return interceptor.intercept(new Invocation(target, method, args)); } return method.invoke(target, args); } catch (Exception e) { throw ExceptionUtil.unwrapThrowable(e); } } private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) { //获得Interceptor注解,@Signature中的type(要拦截的类),method(拦截类的方法)和args(拦截器用于这些类中) Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class); // issue #251 if (interceptsAnnotation == null) { throw new PluginException("No @Intercepts annotation was found in interceptor " + interceptor.getClass().getName()); } //获得注解type,method 和args生成一个signature数组 Signature[] sigs = interceptsAnnotation.value(); Map<Class<?>, Set<Method>> signatureMap = new HashMap<Class<?>, Set<Method>>(); for (Signature sig : sigs) { Set<Method> methods = signatureMap.get(sig.type()); if (methods == null) { methods = new HashSet<Method>(); signatureMap.put(sig.type(), methods); } try { //获得类的方法 Method method = sig.type().getMethod(sig.method(), sig.args()); methods.add(method); } catch (NoSuchMethodException e) { throw new PluginException("Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e, e); } } return signatureMap; } //获得所有接口 private static Class<?>[] getAllInterfaces(Class<?> type, Map<Class<?>, Set<Method>> signatureMap) { Set<Class<?>> interfaces = new HashSet<Class<?>>(); while (type != null) { //获得接口 for (Class<?> c : type.getInterfaces()) { if (signatureMap.containsKey(c)) { interfaces.add(c); } } //获得父类 type = type.getSuperclass(); } //返回一个接口的数组 return interfaces.toArray(new Class<?>[interfaces.size()]); } }
相关文章推荐
- Mybatis 源码之Plugin类解析
- [JWFD开源工作流]最新的项目工作要点
- iOS下app的生命周期
- c++ 时间类型详解(time_t和tm)
- Mybatis 源码之Plugin类解析
- 创建ROS服务端(service)和客户端(client)
- Jquery
- 软件测试_Badboy自动化测试工具11_Jmeter并发测试
- 蓝桥杯-高斯日记
- Android 深入理解Android中的自定义属性
- Android 轻量级sqlite orm 框架
- thinkphp源码解析 (Version 3.1) -2 /Lib/Core/Think.class
- [ACM] POJ 3254 Corn Fields(状态压缩)
- 与独立、自由说再见!微信是怎样扼杀了它们
- jquery——滚动条插件jscroll.js
- 无法解析的外部符号 "public: __thiscall BasePlugin::BasePlugin(class QObject *)"
- CentOS6.5下编译spark1.6.0源码
- Android RecyclerView 使用完全解析 体验艺术般的控件
- MATLABtextscan函数中参数delimiter的使用
- 阿岳之_mariadb安装篇(一)