网站建设源程序清单wordpress mirana

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

网站建设源程序清单,wordpress mirana,网站内容更新软件,网页制作平台哪家好一#xff1a; 前言 我们尝试在前几篇文章的内容中串联起来#xff0c;防止各位不知所云。 1#xff1a;背景 我们基于Mybatis作为后台Orm框架进行编码的时候#xff0c;有两种方式。 //编码方式1 UserDao userDao sqlSession.getMapper(UserDao.class); userDao.quer…一 前言 我们尝试在前几篇文章的内容中串联起来防止各位不知所云。 1背景 我们基于Mybatis作为后台Orm框架进行编码的时候有两种方式。 //编码方式1 UserDao userDao sqlSession.getMapper(UserDao.class); userDao.queryAllUser(Map map); //有同学质疑为毛我从来没有sqlSesseion.getMapper(..)是因为我们使用Spring或者 //boot的时候右边给你封装了导致你直接在Service里边把UserDao进行了注入直接 //右边的你可能压根就没有机会写。//编码方式2 sqlSession.select(com.shit.user.UserDao.queryAllUser,Map map);我们提到了最为底层的是下边这种方式第一种方式是基于动态代理的技术实现的底层也是第二种方式基于此我们开始探索了动态代理的这种方式整套流程下来是怎么玩的。 UserDao userDao SqlSession.getMapper(User.class) userDao.queryuserById(); userDao.queryUsers();2代理设计模式动态代理的一些特点简述 这里的userDao是DAO接口的实现类的对象那么我们就会有一个疑问UserDao这个接口实现类在哪里呢 这个Dao接口的实现类我们是见不到的因为这里是一个典型的动态字节码技术这个类是在虚拟机当中运行时创建的。虚拟机运行结束的时候这个类就消失了 这和我们之前的这些类不一样我们之前写的这些类就是实实在在的文件在我们的硬盘当中通过JVM的类加载的方式读到虚拟机的内存当中。这是我们传统意义上的一个类的创建的方式通过复杂的类加载机制将这个类加载到JVM虚拟机当中之后我们在这个类的Class对象创建出来。 动态字节码技术的特点是类的文件自始至终就没有直接就在虚拟机当中的内存当中去创建进而创建这个类的Class对象。是JVM在运行时的时候基于动态字节码技术将这个类创建出来的操作。 这就是为什么我们知道有这么一个类的存在有这么一个类的对象的存在但是我们就看不到的原因。 创建完成之后就按照多态的特点代理对象地址保存在这个接口的引用类型下边。按照多态的原则所以我们才可以有这个效果。 3使用代理设计模式场景 1)为原始对象目标增加额外功能 ps如果是和原始功能没有半毛钱关系的内容才叫做额外功能与原始功能有关系的功能就不太算是额外功能了这种情况下推进使用装饰器模式。 这个场景典型的Spring的AOP的功能。 2)远程代理远程代理 ps远程代理这时候额外功能就变成1网络连接:2数据传输嘛。这个最典型的就是Dubbo远程代理代理的是远程服务。 3)无中生有只有接口除了接口毛都没有 ps这个最符合的就是Mybatis的Dao层的实现类的处理了。接口实现类这个东西我们真的看不见但是运行时确实可以体现出来。 在这三个场景下我们需要考虑用到代理设计模式第三种是典型的动态代理。而动态代理的典型的编码是 Proxy.newProxyInstance(AssistantToHistoryPriceRule.class.getClassLoader(),new Class[]{BillSystemConfigGateWay.class}, new InvocationHandler(){Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(额外功能输出……);return null;}}); 二实现类该如何去实现预定的功能呢 1猜想Mybatis的代理流程 我们现在有一个Ineterface接口中有这样的一个方法实现类实现之后应该大致张这个样子 以下这个是我们的大致流程猜想当然最终结果肯定是与Mybatis的具体实现大差不差的。 interface UserDao{ListUser queryAllUsers();save(User user) }UserDaoImpl implements UserDAO {queryAllUsers(){sqlSession.select(….);}save(){sqlSession.insert(namespace.id,参数);} }类加载器接口额外功能处理Handler三个条件满足之后运行时会把这个代理对象给创建出来。 2模拟Mybatis代理对象创建 Testpublic void testProxy() throws IOException {InputStream inputStream Resources.getResourceAsStream(mybatis-config.xml);SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession sqlSessionFactory.openSession();Class[] interfaces new Class[]{UserDAO.class};UserDAO userDAO (UserDAO) Proxy.newProxyInstance(TestMybatis.class.getClassLoader(),interfaces,new MyMapperProxy(sqlSession,UserDAO.class));ListUser users userDAO.queryAllUsersByPage();for (User user : users) {System.out.println(user user);}}public class MyMapperProxy implements InvocationHandler {private SqlSession sqlSession;private Class daoClass;public MyMapperProxy(SqlSession sqlSession, Class daoClass) {this.sqlSession sqlSession;this.daoClass daoClass;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(daoClass.getName() . method.getName());return sqlSession.selectList(daoClass.getName() . method.getName());} }这一步的创建代理的操作就等同于我们之前当中的SqlSession.getMapper(UserDao.class)的操作。
三Mybatis代理对象创建的源码如下 Mybatis当中完成代理创建的核心类型是MapperProxy和MapperProcyFactory MapperProcyFactory是个工厂他的作用就是创建代理工厂底层设计的过程中完成的就是Proxy.newProxyInstance()为我们创建代理对象 MapperProxy实现了InvocationHandler接口他就是用调用具体method的。 /*** author Lasse Voss/ public class MapperProxyFactoryT {private final ClassT mapperInterface;private final MapMethod, MapperMethod methodCache new ConcurrentHashMapMethod, MapperMethod();public MapperProxyFactory(ClassT mapperInterface) {this.mapperInterface mapperInterface;}public ClassT getMapperInterface() {return mapperInterface;}public MapMethod, MapperMethod getMethodCache() {return methodCache;}SuppressWarnings(unchecked)protected T newInstance(MapperProxyT mapperProxy) {return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);}public T newInstance(SqlSession sqlSession) {final MapperProxyT mapperProxy new MapperProxyT(sqlSession, mapperInterface, methodCache);return newInstance(mapperProxy);}}/** author Clinton Begin* author Eduardo Macarron/ public class MapperProxyT implements InvocationHandler, Serializable {private static final long serialVersionUID -6424540398559729838L;private final SqlSession sqlSession;private final ClassT mapperInterface;private final MapMethod, MapperMethod methodCache;public MapperProxy(SqlSession sqlSession, ClassT mapperInterface, MapMethod, MapperMethod methodCache) {this.sqlSession sqlSession;this.mapperInterface mapperInterface;this.methodCache methodCache;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {if (Object.class.equals(method.getDeclaringClass())) {return method.invoke(this, args);} else if (isDefaultMethod(method)) {return invokeDefaultMethod(proxy, method, args);}} catch (Throwable t) {throw ExceptionUtil.unwrapThrowable(t);}final MapperMethod mapperMethod cachedMapperMethod(method);return mapperMethod.execute(sqlSession, args);}private MapperMethod cachedMapperMethod(Method method) {MapperMethod mapperMethod methodCache.get(method);if (mapperMethod null) {mapperMethod new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());methodCache.put(method, mapperMethod);}return mapperMethod;}UsesJava7private Object invokeDefaultMethod(Object proxy, Method method, Object[] args)throws Throwable {final ConstructorMethodHandles.Lookup constructor MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);if (!constructor.isAccessible()) {constructor.setAccessible(true);}final Class? declaringClass method.getDeclaringClass();return constructor.newInstance(declaringClass,MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED| MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC).unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args);}/** Backport of java.lang.reflect.Method#isDefault()*/private boolean isDefaultMethod(Method method) {return (method.getModifiers() (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) Modifier.PUBLIC method.getDeclaringClass().isInterface();} }public class MapperMethod {private final SqlCommand command;private final MethodSignature method;public MapperMethod(Class? mapperInterface, Method method, Configuration config) {this.command new SqlCommand(config, mapperInterface, method);this.method new MethodSignature(config, mapperInterface, method);}public Object execute(SqlSession sqlSession, Object[] args) {Object result;switch (command.getType()) {case INSERT: {Object param method.convertArgsToSqlCommandParam(args);result rowCountResult(sqlSession.insert(command.getName(), param));break;}case UPDATE: {Object param method.convertArgsToSqlCommandParam(args);result rowCountResult(sqlSession.update(command.getName(), param));break;}case DELETE: {Object param method.convertArgsToSqlCommandParam(args);result rowCountResult(sqlSession.delete(command.getName(), param));break;}case SELECT:if (method.returnsVoid() method.hasResultHandler()) {executeWithResultHandler(sqlSession, args);result null;} else if (method.returnsMany()) {result executeForMany(sqlSession, args);} else if (method.returnsMap()) {result executeForMap(sqlSession, args);} else if (method.returnsCursor()) {result executeForCursor(sqlSession, args);} else {Object param method.convertArgsToSqlCommandParam(args);result sqlSession.selectOne(command.getName(), param);}break;case FLUSH:result sqlSession.flushStatements();break;default:throw new BindingException(Unknown execution method for: command.getName());}if (result null method.getReturnType().isPrimitive() !method.returnsVoid()) {throw new BindingException(Mapper method command.getName() attempted to return null from a method with a primitive return type ( method.getReturnType() ).);}return result;}private Object rowCountResult(int rowCount) {final Object result;if (method.returnsVoid()) {result null;} else if (Integer.class.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType())) {result rowCount;} else if (Long.class.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType())) {result (long)rowCount;} else if (Boolean.class.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType())) {result rowCount 0;} else {throw new BindingException(Mapper method command.getName() has an unsupported return type: method.getReturnType());}return result;}private void executeWithResultHandler(SqlSession sqlSession, Object[] args) {MappedStatement ms sqlSession.getConfiguration().getMappedStatement(command.getName());if (!StatementType.CALLABLE.equals(ms.getStatementType()) void.class.equals(ms.getResultMaps().get(0).getType())) {throw new BindingException(method command.getName() needs either a ResultMap annotation, a ResultType annotation, or a resultType attribute in XML so a ResultHandler can be used as a parameter.);}Object param method.convertArgsToSqlCommandParam(args);if (method.hasRowBounds()) {RowBounds rowBounds method.extractRowBounds(args);sqlSession.select(command.getName(), param, rowBounds, method.extractResultHandler(args));} else {sqlSession.select(command.getName(), param, method.extractResultHandler(args));}}private E Object executeForMany(SqlSession sqlSession, Object[] args) {ListE result;Object param method.convertArgsToSqlCommandParam(args);if (method.hasRowBounds()) {RowBounds rowBounds method.extractRowBounds(args);result sqlSession.EselectList(command.getName(), param, rowBounds);} else {result sqlSession.EselectList(command.getName(), param);}// issue #510 Collections arrays supportif (!method.getReturnType().isAssignableFrom(result.getClass())) {if (method.getReturnType().isArray()) {return convertToArray(result);} else {return convertToDeclaredCollection(sqlSession.getConfiguration(), result);}}return result;}private T CursorT executeForCursor(SqlSession sqlSession, Object[] args) {CursorT result;Object param method.convertArgsToSqlCommandParam(args);if (method.hasRowBounds()) {RowBounds rowBounds method.extractRowBounds(args);result sqlSession.TselectCursor(command.getName(), param, rowBounds);} else {result sqlSession.TselectCursor(command.getName(), param);}return result;}private E Object convertToDeclaredCollection(Configuration config, ListE list) {Object collection config.getObjectFactory().create(method.getReturnType());MetaObject metaObject config.newMetaObject(collection);metaObject.addAll(list);return collection;}SuppressWarnings(unchecked)private E Object convertToArray(ListE list) {Class? arrayComponentType method.getReturnType().getComponentType();Object array Array.newInstance(arrayComponentType, list.size());if (arrayComponentType.isPrimitive()) {for (int i 0; i list.size(); i) {Array.set(array, i, list.get(i));}return array;} else {return list.toArray((E[])array);}}private K, V MapK, V executeForMap(SqlSession sqlSession, Object[] args) {MapK, V result;Object param method.convertArgsToSqlCommandParam(args);if (method.hasRowBounds()) {RowBounds rowBounds method.extractRowBounds(args);result sqlSession.K, VselectMap(command.getName(), param, method.getMapKey(), rowBounds);} else {result sqlSession.K, VselectMap(command.getName(), param, method.getMapKey());}return result;}public static class ParamMapV extends HashMapString, V {private static final long serialVersionUID -2212268410512043556L;Overridepublic V get(Object key) {if (!super.containsKey(key)) {throw new BindingException(Parameter key not found. Available parameters are keySet());}return super.get(key);}}public static class SqlCommand {private final String name;private final SqlCommandType type;public SqlCommand(Configuration configuration, Class? mapperInterface, Method method) {final String methodName method.getName();final Class? declaringClass method.getDeclaringClass();MappedStatement ms resolveMappedStatement(mapperInterface, methodName, declaringClass,configuration);if (ms null) {if (method.getAnnotation(Flush.class) ! null) {name null;type SqlCommandType.FLUSH;} else {throw new BindingException(Invalid bound statement (not found): mapperInterface.getName() . methodName);}} else {name ms.getId();type ms.getSqlCommandType();if (type SqlCommandType.UNKNOWN) {throw new BindingException(Unknown execution method for: name);}}}public String getName() {return name;}public SqlCommandType getType() {return type;}private MappedStatement resolveMappedStatement(Class? mapperInterface, String methodName,Class? declaringClass, Configuration configuration) {String statementId mapperInterface.getName() . methodName;if (configuration.hasStatement(statementId)) {return configuration.getMappedStatement(statementId);} else if (mapperInterface.equals(declaringClass)) {return null;}for (Class? superInterface : mapperInterface.getInterfaces()) {if (declaringClass.isAssignableFrom(superInterface)) {MappedStatement ms resolveMappedStatement(superInterface, methodName,declaringClass, configuration);if (ms ! null) {return ms;}}}return null;}}public static class MethodSignature {private final boolean returnsMany;private final boolean returnsMap;private final boolean returnsVoid;private final boolean returnsCursor;private final Class? returnType;private final String mapKey;private final Integer resultHandlerIndex;private final Integer rowBoundsIndex;private final ParamNameResolver paramNameResolver;public MethodSignature(Configuration configuration, Class? mapperInterface, Method method) {Type resolvedReturnType TypeParameterResolver.resolveReturnType(method, mapperInterface);if (resolvedReturnType instanceof Class?) {this.returnType (Class?) resolvedReturnType;} else if (resolvedReturnType instanceof ParameterizedType) {this.returnType (Class?) ((ParameterizedType) resolvedReturnType).getRawType();} else {this.returnType method.getReturnType();}this.returnsVoid void.class.equals(this.returnType);this.returnsMany configuration.getObjectFactory().isCollection(this.returnType) || this.returnType.isArray();this.returnsCursor Cursor.class.equals(this.returnType);this.mapKey getMapKey(method);this.returnsMap this.mapKey ! null;this.rowBoundsIndex getUniqueParamIndex(method, RowBounds.class);this.resultHandlerIndex getUniqueParamIndex(method, ResultHandler.class);this.paramNameResolver new ParamNameResolver(configuration, method);}public Object convertArgsToSqlCommandParam(Object[] args) {return paramNameResolver.getNamedParams(args);}public boolean hasRowBounds() {return rowBoundsIndex ! null;}public RowBounds extractRowBounds(Object[] args) {return hasRowBounds() ? (RowBounds) args[rowBoundsIndex] : null;}public boolean hasResultHandler() {return resultHandlerIndex ! null;}public ResultHandler extractResultHandler(Object[] args) {return hasResultHandler() ? (ResultHandler) args[resultHandlerIndex] : null;}public String getMapKey() {return mapKey;}public Class? getReturnType() {return returnType;}public boolean returnsMany() {return returnsMany;}public boolean returnsMap() {return returnsMap;}public boolean returnsVoid() {return returnsVoid;}public boolean returnsCursor() {return returnsCursor;}private Integer getUniqueParamIndex(Method method, Class? paramType) {Integer index null;final Class?[] argTypes method.getParameterTypes();for (int i 0; i argTypes.length; i) {if (paramType.isAssignableFrom(argTypes[i])) {if (index null) {index i;} else {throw new BindingException(method.getName() cannot have multiple paramType.getSimpleName() parameters);}}}return index;}private String getMapKey(Method method) {String mapKey null;if (Map.class.isAssignableFrom(method.getReturnType())) {final MapKey mapKeyAnnotation method.getAnnotation(MapKey.class);if (mapKeyAnnotation ! null) {mapKey mapKeyAnnotation.value();}}return mapKey;}}} 2核心对象的拆解 1MapMethod对象 private final SqlCommand command;private final MethodSignature method;public MapperMethod(Class? mapperInterface, Method method, Configuration config) {this.command new SqlCommand(config, mapperInterface, method);this.method new MethodSignature(config, mapperInterface, method);} }MapMethod当中需要两个成员变量SqlCommandMethodSignature 把Method(Dao接口中的某一个方法的对象再次包装了一层包装成了MapMethod对象)增添了SqlCommandMethodSignature两个成员。 2SqlCommand对象 包含两个关键成员 private final String name; private final SqlCommandType type;private final String name;private final SqlCommandType type;//构造方法public SqlCommand(Configuration configuration, Class? mapperInterface, Method method) {final String methodName method.getName();final Class? declaringClass method.getDeclaringClass();MappedStatement ms resolveMappedStatement(mapperInterface, methodName, declaringClass,configuration);if (ms null) {if (method.getAnnotation(Flush.class) ! null) {name null;type SqlCommandType.FLUSH;} else {throw new BindingException(Invalid bound statement (not found): mapperInterface.getName() . methodName);}} else {name ms.getId();type ms.getSqlCommandType();if (type SqlCommandType.UNKNOWN) {throw new BindingException(Unknown execution method for: name);}}}name是nameSpaceidtype是insert,delete,update,select 3MethodSignature 方法的入参类型和返回值类型。对SQL入参和SQL执行后的返回值的处理提供类型机制。 到这里我们是不是就有点清晰了Mybatis中对代理设计模式的应用是这个样子的 1这个流程中几个核心的成员 MappedProxyFactory执行Proxy.newProxyInstance(ClassLoader,UserDao.class,InvocationHandler); 来创建代理对象 MappedProxy:InvocationHandler的实习类原始功能都没有的这种代理设计模式中的功能模块 具体进行sqlSession.select,insert,update,delete的模块 MapMethod 是对方法对象的二次封装我们知道Mybatis中UserDao中的method可以提供nameSpace.id嘛 这就是他的作用。 SqlCommand:对象nameSpace.id基于构造方法放到了name属性里边type是method增删改查的类型描述 MethodSignature对方法入参和方法返参的描述