版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ty497122758/article/details/80339599
mybatis的mapper代理是用的jdk的动态代理,请看mybatis的如下代码:
/**
* 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.binding;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.ibatis.session.SqlSession;
/**
* @author Lasse Voss
*/
public class MapperProxyFactory<T> {
private final Class<T> mapperInterface;
private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>();
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
public Class<T> getMapperInterface() {
return mapperInterface;
}
public Map<Method, MapperMethod> getMethodCache() {
return methodCache;
}
@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
//这里就是mybatis,创建mapper代理的关键代码,用的JDK的Proxy的方法
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
}
下面我们来实现,用到的就是JDK的InvocationHandler接口和Proxy类
先写Mapper接口
public interface UserMapper {
public void save(String name, int age);
}
然后实现InvocationHandler接口,复写invoke方法执行实际的代码
import second.UserMapper;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
/**
* 只写接口,不用写实现类的动态代理,类似mybatis的mapper
*/
public class MapperProxy implements InvocationHandler{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.printf("class:%s, method:%s, args:%s, return:%s\n",
proxy.getClass().getName(),
method.getName(),
Arrays.toString(args),
method.getReturnType().getName());
//TODO 在这里去动态实现代理类的行为
if("save".equals(method.getName())){
//TODO 执行sql的insert语句
}
return null;
}
}
最后用Proxy的newInstance静态方法,实例化代理类
public static void main(String args[]){
Class<UserMapper> cla = UserMapper.class;
UserMapper userProxy = (UserMapper)Proxy.newProxyInstance(cla.getClassLoader(), new Class[]{cla}, new MapperProxy());
userProxy.save("tuyou", 25);
}
到此实现完毕!