十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章将为大家详细讲解有关怎么在mybatis中实现扩展,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
创新互联2013年开创至今,先为建德等服务建站,建德等地企业,进行企业商务咨询服务。为建德企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
先看下拦截器的核心接口
public interface Interceptor { Object intercept(Invocation invocation) throws Throwable; Object plugin(Object target); void setProperties(Properties properties); }
其中intercept方法是核心方法,拦截器的实现,plugin方法是用于配置哪些对哪些执行器进行拦截
继续看源码,可以看到mybatis的拦截是使用了jdk的动态代理实现的,本质上是一种代理机制
public class Plugin implements InvocationHandler { private final Object target; private final Interceptor interceptor; private final Map, Set > signatureMap; private Plugin(Object target, Interceptor interceptor, Map , Set > signatureMap) { this.target = target; this.interceptor = interceptor; this.signatureMap = signatureMap; } public static Object wrap(Object target, Interceptor interceptor) { Map , Set > 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 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); } } ...... }
mybatis的这个Plugin就是代理类,这个代理类是在org.apache.ibatis.plugin.Interceptor#plugin
方法中初始化的(调用org.apache.ibatis.plugin.Plugin#wrap
),一个Plugin包含一个Intercepter,以及该Intercepter相关的注解配置信息,当对拦截对象的对应方法进行执行的时候,都会根据这些注解配置来判断是否需要执行该代理拦截(org.apache.ibatis.plugin.Plugin#invoke
)
再看下plugin是如何被加载的:
public class InterceptorChain { private final Listinterceptors = new ArrayList (); 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 getInterceptors() { return Collections.unmodifiableList(interceptors); } }
org.apache.ibatis.plugin.Interceptor#plugin
是在org.apache.ibatis.plugin.InterceptorChain#pluginAll
方法中调用的,我们可以看到,如果一个应用中注册了多个拦截器,那么实际上是会进行一个for循环的加载,由于上面说到了,加载一次,本质上是对mybatis的执行期进行一次代理包装,那么加载多次的话,就会代理包装多次,实际上就是一种多重代理了,这样就保证了每次调用都会按照代理顺序进行调用和返回的处理
可以看到,在做这些mybatis执行器初始化的时候,都会进行拦截器链的加载
关于怎么在mybatis中实现扩展就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。