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

上海普陀网站建设wordpress ip被禁用

上海普陀网站建设,wordpress ip被禁用,吴中区住房和城乡建设局网站,山东省城乡建设部网站转载自 mybatis源码阅读(八) ---Interceptor了解一下 1 Intercetor MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下#xff0c;MyBatis允许使用插件来拦截的方法调用包括#xff1a; Executor (update, query, flushStatements, commit, rollba…转载自  mybatis源码阅读(八) ---Interceptor了解一下  1 Intercetor MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下MyBatis允许使用插件来拦截的方法调用包括 Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) 拦截执行器的方法 ParameterHandler (getParameterObject, setParameters) 拦截参数的处理 ResultSetHandler (handleResultSets, handleOutputParameters) 拦截结果集的处理 StatementHandler (prepare, parameterize, batch, update, query) 拦截Sql语法构建的处理 public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {ParameterHandler parameterHandler mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);parameterHandler (ParameterHandler) interceptorChain.pluginAll(parameterHandler);return parameterHandler; }public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,ResultHandler resultHandler, BoundSql boundSql) {ResultSetHandler resultSetHandler new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);resultSetHandler (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);return resultSetHandler; }public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {StatementHandler statementHandler new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);statementHandler (StatementHandler) interceptorChain.pluginAll(statementHandler);return statementHandler; }public Executor newExecutor(Transaction transaction) {return newExecutor(transaction, defaultExecutorType); }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);}executor (Executor) interceptorChain.pluginAll(executor);return executor; } InterceptorChain里保存了所有的拦截器它在mybatis初始化的时候创建。上面interceptorChain.pluginAll(executor)的含义是调用拦截器链里的每个拦截器依次对executor进行plugin插入拦截代码如下 public class InterceptorChain {private final ListInterceptor interceptors new ArrayListInterceptor();public Object pluginAll(Object target) {for (Interceptor interceptor : interceptors) {target interceptor.plugin(target);}return target;}public void addInterceptor(Interceptor interceptor) {interceptors.add(interceptor);}public ListInterceptor getInterceptors() {return Collections.unmodifiableList(interceptors);}} Interceptor 结构 public interface Interceptor {Object intercept(Invocation invocation) throws Throwable;Object plugin(Object target);void setProperties(Properties properties);} 2.自定义拦截器 官方源码例子 Intercepts({Signature(type Executor.class, method query,args {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})}) public class ExamplePlugin implements Interceptor {private Properties properties;Overridepublic Object intercept(Invocation invocation) throws Throwable {return invocation.proceed();}Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}Overridepublic void setProperties(Properties properties) {this.properties properties;}public Properties getProperties() {return properties;}} mybatis-config.xml配置 pluginsplugin interceptororg.lpf.interceptor.ExamplePlugin/plugin /plugins 每一个拦截器都必须实现上面的三个方法其中 Object intercept(Invocation invocation)是实现拦截逻辑的地方内部要通过invocation.proceed()显式地推进责任链前进也就是调用下一个拦截器拦截目标方法。 Object plugin(Object target)就是用当前这个拦截器生成对目标target的代理实际是通过Plugin.wrap(target,this)来完成的把目标target和拦截器this传给了包装函数。 setProperties(Properties properties)用于设置额外的参数参数配置在拦截器的Properties节点里。 注解里描述的是指定拦截方法的签名 [type,method,args] 即对哪种对象的哪种方法进行拦截它在拦截前用于决断。 定义自己的Interceptor最重要的是要实现plugin方法和intercept方法在plugin方法中我们可以决定是否要进行拦截进而决定要返回一个什么样的目标对象。而intercept方法就是要进行拦截的时候要执行的方法。 对于plugin方法而言其实Mybatis已经为我们提供了一个实现。Mybatis中有一个叫做Plugin的类里面有一个静态方法wrap(Object target,Interceptor interceptor)通过该方法可以决定要返回的对象是目标对象还是对应的代理。这里我们先来看一下Plugin的源码 /*** author Clinton Begin* 这个类是Mybatis拦截器的核心,大家可以看到该类继承了InvocationHandler* 又是JDK动态代理机制*/ public class Plugin implements InvocationHandler {//目标对象private final Object target;// 拦截器private final Interceptor interceptor;//记录需要被拦截的类与方法 提高性能private final MapClass?, SetMethod signatureMap;private Plugin(Object target, Interceptor interceptor, MapClass?, SetMethod signatureMap) {this.target target;this.interceptor interceptor;this.signatureMap signatureMap;}//一个静态方法,对一个目标对象进行包装生成代理类。public static Object wrap(Object target, Interceptor interceptor) {//首先根据interceptor上面定义的注解 获取需要拦截的信息MapClass?, SetMethod signatureMap getSignatureMap(interceptor);//目标对象的ClassClass? type target.getClass();//返回需要拦截的接口信息Class?[] interfaces getAllInterfaces(type, signatureMap);//如果长度为0 则返回代理类 否则不做处理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 {//通过method参数定义的类 去signatureMap当中查询需要拦截的方法集合SetMethod 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);}}//根据拦截器接口Interceptor实现类上面的注解获取相关信息private static MapClass?, SetMethod getSignatureMap(Interceptor interceptor) {//获取注解信息InterceptsIntercepts interceptsAnnotation interceptor.getClass().getAnnotation(Intercepts.class);// issue #251if (interceptsAnnotation null) {//为空则抛出异常throw new PluginException(No Intercepts annotation was found in interceptor interceptor.getClass().getName()); }//获得Signature注解信息 是一个数组Signature[] sigs interceptsAnnotation.value();MapClass?, SetMethod signatureMap new HashMapClass?, SetMethod();//循环注解信息for (Signature sig : sigs) {//根据Signature注解定义的type信息去signatureMap当中查询需要拦截方法的集合SetMethod methods signatureMap.get(sig.type());if (methods null) { //第一次肯定为null 就创建一个并放入signatureMapmethods new HashSetMethod();signatureMap.put(sig.type(), methods);}try {//找到sig.type当中定义的方法 并加入到集合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;}//根据对象类型与signatureMap获取接口信息private static Class?[] getAllInterfaces(Class? type, MapClass?, SetMethod signatureMap) {SetClass? interfaces new HashSetClass?();//循环type类型的接口信息 如果该类型存在与signatureMap当中则加入到set当中去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()]);}} 3.代理链上的拦截 我们再次结合(Executor)interceptorChain.pluginAll(executor)这个语句来看这个语句内部对executor执行了多次plugin,第一次plugin后通过Plugin.wrap方法生成了第一个代理类姑且就叫executorProxy1这个代理类的target属性是该executor对象。第二次plugin后通过Plugin.wrap方法生成了第二个代理类姑且叫executorProxy2这个代理类的target属性是executorProxy1...这样通过每个代理类的target属性就构成了一个代理链从最后一个executorProxyN往前查找通过target属性可以找到最原始的executor类 当Configuration调用newExecutor方法的时候由于Executor接口的update(MappedStatement ms, Object parameter)方法被拦截器被截获。因此最终返回的是一个代理类Plugin而不是Executor。这样调用方法的时候如果是个代理类那么会执行 //代理对象每次调用的方法 Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {//通过method参数定义的类 去signatureMap当中查询需要拦截的方法集合SetMethod 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);} } 那么会执行Interceptor接口的interceptor方法 如下 public Object intercept(Invocation invocation) throws Throwable {return invocation.proceed(); } 传递给拦截器的是一个Invocation对象如下 public class Invocation {private final Object target;private final Method method;private 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);} 可以看到Invocation类保存了代理对象的目标类执行的目标类方法以及传递给它的参数。 在每个拦截器的intercept方法内最后一个语句一定是return invocation.proceed()不这么做的话拦截器链就断了你的mybatis基本上就不能正常工作了。invocation.proceed()只是简单的调用了下target的对应方法如果target还是个代理就又回到了上面的Plugin.invoke方法了。这样就形成了拦截器的调用链推进。 4.总结 总体来说MyBatis拦截器还是很简单的拦截器本身不需要太多的知识点但是学习拦截器需要对MyBatis中的各个接口很熟悉因为拦截器涉及到了各个接口的知识点。 我们假设在MyBatis配置了一个插件在运行时会发生什么 所有可能被拦截的处理类都会生成一个代理处理类代理在执行对应方法时判断要不要执行插件中的拦截方法执行插接中的拦截方法后推进目标的执行 如果有N个插件就有N个代理每个代理都要执行上面的逻辑。这里面的层层代理要多次生成动态代理是比较影响性能的。虽然能指定插件拦截的位置但这个是在执行方法时动态判断初始化的时候就是简单的把插件包装到了所有可以拦截的地方。 因此在编写插件时需注意以下几个原则 不编写不必要的插件实现plugin方法时判断一下目标类型是本插件要拦截的对象才执行Plugin.wrap方法否者直接返回目标本省这样可以减少目标被代理的次数。
http://www.lebaoying.cn/news/9938.html

相关文章:

  • 培训制作网站源码聊城做网站的公司流程
  • 基于php mysql的网站开发苏州网站推广服务
  • 免费申请com网站希爱力双效片用后感受
  • 网站服务器错误怎么办莱芜 做网站 公司
  • 口碑营销的概念专业做汽车网站优化排名
  • 做网站策划容易遇到哪些问题建设银行网站修改手机号
  • 个人网站是商业的吗临沂制作网站软件
  • 小程序开发 网站建设谷歌seo实战教程
  • 网站策划做营销推广好项目网
  • 宁波龙山建设有限公司网站怎么建设一个购买卡密的网站
  • 手机网站开发哪家好网站 后台 数据 下载
  • 浅谈京东企业的电子商务网站建设免费发布广告信息平台
  • 制作一个专门浏览图片的网站做网站合同封面
  • 北京网站建设报价郑州的网络科技有限公司
  • 各种浏览器网站大全酒店网站建设描述
  • 图书馆新生专栏网站建设动漫制作专业论文
  • 通辽网站seo国企有没有必要建设网站
  • 怎么做网站图标克隆网站带后台
  • 福建省住房城乡和城乡建设厅网站被黑的网站
  • 个人做公司网站东莞商业网站建设常识
  • 没有网站能做淘宝客吗电话销售做网站推销
  • 空包网站建设南昌建设网站公司
  • 王烨飞微博朝阳seo网站建设
  • 男女做暧暧试看网站如何做网站淘客
  • 永康网站建设的公司引流推广怎么做
  • 网站开网站开发设计公司西安市住房和城乡建设局门户网站
  • 徐州网站排名系统wordpress怎么做博客
  • 陕西省建设厅执业资格注册中心网站wordpress禁止自适应
  • 安吉做网站建设网站公司需要哪些证件
  • 360提交网站做视频的网站有哪些