当前位置: 首页 > news >正文

乐山住房和规划建设局门户网站做网站的费用

乐山住房和规划建设局门户网站,做网站的费用,html5软件,辽宁响应式网站建设推荐mybatis源码下载 https://github.com/mybatis/mybatis-3,本文分析源码版本3.4.5 mybatis启动大致流程 在看这篇文章前,建议查看我另一篇文章,以了解框架启动的流程和框架中一些重要对象:https://blog.csdn.net/Aqu415/article/…

mybatis源码下载

https://github.com/mybatis/mybatis-3,本文分析源码版本3.4.5

mybatis启动大致流程

在看这篇文章前,建议查看我另一篇文章,以了解框架启动的流程和框架中一些重要对象:https://blog.csdn.net/Aqu415/article/details/79049739

可以被插件代理的类

Mybatis中可以被插件的类分为4种,分别是Executor、StatementHandler、ParameterHandler、ResultSetHandler。

InterceptorChain

这里说一个在插件开发过程中比较重要的类,这个类会缓存系统中所有的插件类(一个Configuration对应一个InterceptorChain);InterceptorChain中缓存的插件会在框架启动时伴随解析配置文件中plugins节点完成
InterceptorChain代码如下:

package org.apache.ibatis.plugin;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;/*** @author Clinton Begin*/
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);}
}

我们看看哪些地方调用了该方法:
在这里插入图片描述

调用这个方法的地方有如下(可见上面说的四大对象都是由Configuration这个类创建的):

1、org.apache.ibatis.session.Configuration#newExecutor
2、org.apache.ibatis.session.Configuration#newStatementHandler
3、org.apache.ibatis.session.Configuration#newParameterHandler
4、org.apache.ibatis.session.Configuration#newResultSetHandler

目标对象被代理的时机

我们挑第一个方法来看看,发现目标对象被代理的时机在对象创建后直接调用interceptorChain.pluginAll方法完成的。

  public Executor newExecutor(Transaction transaction, ExecutorType executorType) {executorType = executorType == null ? defaultExecutorType : executorType;executorType = executorType == null ? ExecutorType.SIMPLE : executorType;Executor executor;if (ExecutorType.BATCH == executorType) {executor = new BatchExecutor(this, transaction);} else if (ExecutorType.REUSE == executorType) {executor = new ReuseExecutor(this, transaction);} else {executor = new SimpleExecutor(this, transaction);}if (cacheEnabled) {executor = new CachingExecutor(executor);}// @Aexecutor = (Executor) interceptorChain.pluginAll(executor);return executor;}

@A:调用InterceptorChain对已经创建好的Executor对象进行代理(插件化包装),调用pluginAll方法实则是调用每一个插件的plugin方法

如下是 Executor 的方法定义:


package org.apache.ibatis.executor;import java.sql.SQLException;
import java.util.List;import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.transaction.Transaction;/*** @author Clinton Begin*/
public interface Executor {ResultHandler NO_RESULT_HANDLER = null;int update(MappedStatement ms, Object parameter) throws SQLException;<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;<E> Cursor<E> queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;List<BatchResult> flushStatements() throws SQLException;void commit(boolean required) throws SQLException;void rollback(boolean required) throws SQLException;CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);boolean isCached(MappedStatement ms, CacheKey key);void clearLocalCache();void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);Transaction getTransaction();void close(boolean forceRollback);boolean isClosed();void setExecutorWrapper(Executor executor);
}

这个类主要数据库操作相关的顶级接口,如果要在执行数据库操作较早时机对方法进行拦截,可以对Executor进行插件编写,接口里定义的方法都可以被插件拦截到。

插件的编写

需要实现 org.apache.ibatis.plugin.Interceptor接口,编程模式可以参考框架提供的例子类

package org.apache.ibatis.builder;import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;import java.util.Properties;// @B
@Intercepts({})
public class ExamplePlugin implements Interceptor {private Properties properties;@Overridepublic Object intercept(Invocation invocation) throws Throwable {return invocation.proceed();}@Overridepublic Object plugin(Object target) {// @Areturn Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {this.properties = properties;}public Properties getProperties() {return properties;}
}

@A:调用Plugin类生成一个代理类,返回这个代理对象
@B:完善需要拦截的目标类,指定方法和参数类型(作用后面分析)

工具类Plugin

框架提供一个通用生成代理的工具类 org.apache.ibatis.plugin.Plugin,其实我们可以用Plugin的api来包装目标对象也可以采用自定义的方式;采用Plugin是为了后面更方便使用@Intercepts等注解对目标类和目标方法进行过滤,而不是对所有以上四种类型的所有方法进行拦截;
因为在Plugin内部方法拦截时做了特殊过滤,使用起来更方便。

我们来看看Plugin 类

package org.apache.ibatis.plugin;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;import org.apache.ibatis.reflection.ExceptionUtil;/*** @author Clinton Begin*/
public class Plugin implements InvocationHandler {private final Object target;private final Interceptor interceptor;private final 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;}@Overridepublic 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 #251if (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()]);}
}

这个类其实兼有两大作用
1、生成代理,代理即目标对象与自定义逻辑间的枢纽拦截器(对应wrap方法)
2、自己充当这个拦截器(基于jdk代理模式)
如果分开成两个类的话,分析起来会更清晰一些

invoke

我们知道基于JDK动态代理的代理对象,会在目标方法前执行其invoke方法;我们分析一下这个方法

  @Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {// @ASet<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);}}

@A:这里从缓存里看是否有配置目标类和方法,如果有的话则执行拦截器的intercept方法,也就是插件的intercept方法;
目标类和目标方法是在创建代理对象的时候,通过getSignatureMap返回;其主要是解析插件上的Intercepts注解

插件对真实对象方法拦截时机

1、从以上分析如果有多个插件,那么插件之间会形成上一个插件代理下一个插件的情况;
2、由于生成四大对象时,对目标对象进行了org.apache.ibatis.plugin.InterceptorChain#pluginAll包装,那么框架真正得到的对象就是代理对象,那么其执行方法的时候就是拦截时机

Object intercept(Invocation invocation) throws Throwable;

我们接下来分析一下执行插件的intercept方法时候,传给它的参数具体是什么;其类型是:org.apache.ibatis.plugin.Invocation

package org.apache.ibatis.plugin;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;/*** @author Clinton Begin*/
public class Invocation {// @Aprivate final Object target;
// @Bprivate final Method method;
// @Cprivate final Object[] args;public Invocation(Object target, Method method, Object[] args) {this.target = target;this.method = method;this.args = args;}public Object getTarget() {return target;}public Method getMethod() {return method;}public Object[] getArgs() {return args;}public Object proceed() throws InvocationTargetException, IllegalAccessException {return method.invoke(target, args);}
}

@A:目标对象,即Executor、StatementHandler、ParameterHandler、ResultSetHandler四大类型的真实对象;如果是多层插件代理同一个类型又可能是原始对象,但也有可能是上一个代理对象
@B:方法签名
@C:参数

http://www.shuangfujiaoyu.com/news/20486.html

相关文章:

  • 北京梦创义网站建设免费下载百度并安装
  • wordpress多站点 文章导入电商网站分析
  • 网站小游戏怎么做的优化网站的方法
  • 网站子目录是什么意思百度小程序优化排名
  • iis8出现在网站首页网络营销能干什么工作
  • 中山市网站制作微信营销案例
  • 建立自己的网站平台的好处bt搜索引擎下载
  • 网站这么推广seo推广教学
  • 做网站的电销话术系统优化app
  • 网站建设需求问卷qq群排名优化软件
  • 腾讯地图北斗导航下载广州推广seo
  • 重庆秀山网站建设费用windows优化大师怎么彻底删除
  • 中型网站开发周期百度一下移动版首页
  • 有什么做网站的公司广告网络推广怎么做
  • 哪些网站可以免费做h5seoul是什么品牌
  • 上线一个网站需要多少钱广州网站建设工作室
  • 多就能自己做网站独立站建站需要多少钱
  • 专业的深圳网站建设公司哪家好网络推广工作好做不
  • 做网站详细步骤刷赞网站推广永久
  • 网站为什么改版关键词优化的策略有哪些
  • jsp动态网站开发心得软文广告例子
  • 网站有哪些功能网站托管服务商
  • 货到付款网站怎么做可以推广的平台
  • 人力资源做网站的好处最彻底的手机优化软件
  • 旅行做攻略的网站如何在百度上发布自己的文章
  • 网站规划有前途吗企业培训平台
  • 网站url可以在自己做吗中国大数据平台官网
  • 哪些网站容易被百度收录百度百度地图
  • 网站建设投标书服务方案范本网站优化包括对什么优化
  • 网页设计大赛新闻稿seo和sem的概念