Mybatis源码分析之插件责任链、动态代理
来源:互联网 发布:为什么需要云计算 编辑:程序博客网 时间:2024/05/17 23:57
Mybatis源码分析之插件责任链
public class InterceptorChain { private final List<Interceptor> interceptors = new ArrayList<Interceptor>(); public Object pluginAll(Object target) { for (Interceptor interceptor : interceptors) { target = interceptor.plugin(target); } return target; } //添加责任链处理类 public void addInterceptor(Interceptor interceptor) { interceptors.add(interceptor); } public List<Interceptor> getInterceptors() { return Collections.unmodifiableList(interceptors); }}
Plugin 类实现了JDK动态代理类接口
public class Plugin implements InvocationHandler {//实现jdk动态代理接口 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) { // 构建代理对象 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)) { 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) { 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()); } 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()]); }}
0 0
- Mybatis源码分析之插件责任链、动态代理
- MyBatis 源码分析——动态代理
- JDK动态代理源码分析之二
- Mybatis源码分析(一)--Mapper的动态代理
- mybatis之动态代理
- 【Mybatis】mybatis插件源码分析
- mybatis源码分析之Mapper代理实现分析
- Mybatis源码分析之插件(plugins)源码详解
- mybatis -- 由浅入深分析mybatis通过动态代理实现拦截器(插件)的原理
- 动态代理模式和责任链模式
- MyBatis之Mapper动态代理
- Mybatis之Mapper动态代理
- Mybatis之Mapper动态代理
- Java 动态代理源码分析
- Java 动态代理源码分析
- JDK动态代理源码分析
- cglib动态代理源码分析
- 由浅入深分析mybatis通过动态代理实现拦截器(插件)的原理
- Java并发小结
- 理解FreeRtos的链表
- 实现类似新浪微博、QQ空间等帖子显示(1)——SpannableString说明
- Python spider
- 常见命令
- Mybatis源码分析之插件责任链、动态代理
- 关于EM算法的一些心得感悟
- 设置mysql表名大小写不敏感
- 7 databases in 7 weeks notes——(一)概述
- android6.0推出的一个网络框架XDroidRequest
- php使用websocket编写的简易客服系统源码分析
- Laravel5自动跳转到登陆前页面
- 【html】各种浏览器内核的比较
- 二叉树遍历非递归