MyBatis-3.4.2-源码分析19:Plugins机制研究-初探

显然,Mybatis的插件机制是非常重要的一环,如果不会这个,估计都不好意思跟别人说自己会Mybatis.

首先,写了1个自定义的MyPlugin

package plugin;

import java.util.Properties;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Invocation;

public class MyPlugin implements Interceptor {
	private String prop1;
	private String prop2;

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		new Exception().printStackTrace();
		return invocation;
	}

	@Override
	public Object plugin(Object target) {
		new Exception().printStackTrace();
//		if(target instanceof StatementHandler){
//			StatementHandler handler=(StatementHandler)target;
//			System.out.println("----------------"+handler.getBoundSql().getSql());
//		}
		return target;
	}

	@Override
	public void setProperties(Properties properties) {
		// TODO Auto-generated method stub

	}

	public String getProp1() {
		return prop1;
	}

	public void setProp1(String prop1) {
		this.prop1 = prop1;
	}

	public String getProp2() {
		return prop2;
	}

	public void setProp2(String prop2) {
		this.prop2 = prop2;
	}

}

执行一个范例,打印内容如下:


java.lang.Exception
	at plugin.MyPlugin.plugin(MyPlugin.java:21)
	at org.apache.ibatis.plugin.InterceptorChain.pluginAll(InterceptorChain.java:33)
	at org.apache.ibatis.session.Configuration.newExecutor(Configuration.java:605)
	at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:110)
	at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSession(DefaultSqlSessionFactory.java:50)
	at test.Test.business(Test.java:35)
	at test.Test.main(Test.java:27)




java.lang.Exception
	at plugin.MyPlugin.plugin(MyPlugin.java:21)
	at org.apache.ibatis.plugin.InterceptorChain.pluginAll(InterceptorChain.java:33)
	at org.apache.ibatis.session.Configuration.newParameterHandler(Configuration.java:556)
	at org.apache.ibatis.executor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:72)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:42)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:48)
	at org.apache.ibatis.session.Configuration.newStatementHandler(Configuration.java:572)
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:123)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:212)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.delete(DefaultSqlSession.java:227)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:72)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:66)
	at com.sun.proxy.$Proxy5.deleteRole(Unknown Source)
	at test.Test.business(Test.java:57)
	at test.Test.main(Test.java:27)




java.lang.Exception
	at plugin.MyPlugin.plugin(MyPlugin.java:21)
	at org.apache.ibatis.plugin.InterceptorChain.pluginAll(InterceptorChain.java:33)
	at org.apache.ibatis.session.Configuration.newResultSetHandler(Configuration.java:564)
	at org.apache.ibatis.executor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:73)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:42)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:48)
	at org.apache.ibatis.session.Configuration.newStatementHandler(Configuration.java:572)
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:123)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:212)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.delete(DefaultSqlSession.java:227)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:72)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:66)
	at com.sun.proxy.$Proxy5.deleteRole(Unknown Source)
	at test.Test.business(Test.java:57)
	at test.Test.main(Test.java:27)




java.lang.Exception
	at plugin.MyPlugin.plugin(MyPlugin.java:21)
	at org.apache.ibatis.plugin.InterceptorChain.pluginAll(InterceptorChain.java:33)
	at org.apache.ibatis.session.Configuration.newStatementHandler(Configuration.java:575)
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:123)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:212)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.delete(DefaultSqlSession.java:227)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:72)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:66)
	at com.sun.proxy.$Proxy5.deleteRole(Unknown Source)
	at test.Test.business(Test.java:57)
	at test.Test.main(Test.java:27)

总结就是:

Executor

ParameterHandler

ResultSetHandler

StatementHandler

 

好,我们先研究插件的接口类

/**
 *    Copyright 2009-2015 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.plugin;

import java.util.Properties;

/**
 * @author Clinton Begin
 */
public interface Interceptor {

  Object intercept(Invocation invocation) throws Throwable;

  Object plugin(Object target);

  void setProperties(Properties properties);

}

---下面是关于插件的初始化

at plugin.MyPlugin.<init>(MyPlugin.java:13)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.pluginElement(XMLConfigBuilder.java:248)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:134)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:111)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:82)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:65)
	at test.Test.main(Test.java:23)

定位到代码如下:

private void pluginElement(XNode parent) throws Exception {
		// 如果定义了plugin节点
		if (parent != null) {
			// 遍历每1个子节点
			for (XNode child : parent.getChildren()) {
				// 获取interceptor的值
				String interceptor = child.getStringAttribute("interceptor");
				// 其它子节点作为属性存在
				Properties properties = child.getChildrenAsProperties();
				// 指定的interceptor实例化,所以传递的这个类必须实现Interceptor接口
				Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
				// 属性设置,自己实现
				interceptorInstance.setProperties(properties);
				// 非常重要
				configuration.addInterceptor(interceptorInstance);
				// 看到这里了
			}
		}
	}

转载于:https://my.oschina.net/qiangzigege/blog/882285

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值