欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

MyBatis的运行的核心原理解析(三)

发布时间:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的这篇文章主要介绍了 MyBatis的运行的核心原理解析(三) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

2019独角兽企业重金招聘Python工程师标准>>>

#插件

  • 四大对象在运行得时候,在Configuration对象得创建方法里MyBatis使用了责任链得方式去封装,也就是说我们可以有机会在四大对象调度得时候插入我们自定义得代码区执行一些特殊得要求来满足我们特殊得场景需求,就是MyBatis得插件技术.

插件的接口

MyBatis中使用插件,我们必须实现Interceptor接口,接口的代码如下:

package org.apache.ibatis.plugin; import java.util.Properties; public interface Interceptor {Object intercept(Invocation invocation) throws Throwable;Object plugin(Object target);void setProperties(Properties properties);}
  • intercept():它将直接覆盖你所拦截对象原有的方法,因此它是插件的核心方法。intercept里面有个参数Invocation对象,通过它可以反射调度原来的对象的方法。

  • plugin():里面的参数Object target是被拦截的对象,它的作用是给被拦截对象生成一个代理对象,并且返回它。在MyBatis里直接使用org.apache.ibatis.plugin.Plugin中的wrap静态(static)方法提供了生成代理对象,我们往往使用plugin方法便可以生成一个代理对象了。

    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; }
  • setProperties():允许在plugin元素中配置我们需要的参数,方法在插件初始化的时候就会被调用一次,然后把插件对象存入到配置中,方便后面获取。 在org.apache.ibatis.builder.xml.XMLConfigBuilder我们可以看到: private void pluginElement(XNode parent) throws Exception { if (parent != null) { for (XNode child : parent.getChildren()) { String interceptor = child.getStringAttribute("interceptor"); Properties properties = child.getChildrenAsProperties(); Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance(); interceptorInstance.setProperties(properties); configuration.addInterceptor(interceptorInstance); } } }

其实在解析配置文件的过程中,我们的插件节点和我们配置参数,同时使用反射技术生成对应的插件实例,然后调用插件方法中的setProperties(),设置我们配置的参数,然后将插件实例保存到配置对象里,方便后面的读取使用它。所以插件的实例对象是以开始就被初始化的,不是在使用到的时候才初始化,这样可以提升性能。

Configuration保存插件的方式(初始化完的参数保存在了List<Interceptor> interceptors这个list里面):

public void addInterceptor(Interceptor interceptor) {interceptorChain.addInterceptor(interceptor);}
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类的plugin()可以生成代理对象,在生成代理对象之后将对象存进了Configuration里面,如果需要直接从Configuration实例获取就可以了。从第一个对象(四大对象中的一个)开始,将对象传递给plugin(),然后返回一个代理;如果存在第二个插件,那么我们拿到第一个代理对象,传递给plugin()再返回第一个代理独享的代理......依此类推,拦截器越多,代理的对象就越多(多少个拦截器就多少个代理对象)。保证了每一个插件都可以拦截到真是的对象。这就号比每一个插件都可以一层层的处理拦截的对象。MyBatis的四大对象也是如此处理的。

转载于:https://my.oschina.net/u/3474937/blog/2209371

总结

以上是生活随笔为你收集整理的MyBatis的运行的核心原理解析(三)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。