logging包的阅读

1、java常用的日志框架log4j、log4j2、apache commons log、java.util.logging、slf4j,这些接口都不是很统一,所以mybatis定义了一套统一的日志接口供上层使用,为常用的日志框架提供适配器

2、设计模式的六大原则

    1)单一职责原则

    2)里式替换原则

    3)依赖倒置原则

    4)接口隔离原则

    5)迪米特法则

    6)开放封闭原则

3、mybatis日志模块,使用了适配器模式,提供了多个adapter,将这些第三方组件对外的接口适配成了org.apache.ibatis.logging.Log

4、代理模式的作用

    可以控制真实类的访问,可以在调用前后进行预处理和后置处理

    实现调用类和真实类的解耦

 5、mybatis延迟加载的机制

系统访问数据库时,首先可以得到一个代理对象,此时没有任何真实的数据库操作,当真的需要数据时,通过代理对象完成数据的查询

6、动态代理

package org.apache.ibatis;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class TestInvocationHandler implements InvocationHandler {

    private Object target;

    public TestInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object o, Method method, Object[] args) throws Throwable {
        System.out.println("预处理");
        Object result=method.invoke(target,args);
        System.out.println("后置处理");
        return result;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),target.getClass().getInterfaces(),this);
    }

    public static void main(String[] args) {
        Demo b=new DemoImpl();
        TestInvocationHandler invocationHandler=new TestInvocationHandler(b);
        Demo proxy= (Demo) invocationHandler.getProxy();
        proxy.hello();
    };

}

 

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
    throws IllegalArgumentException
{
    Objects.requireNonNull(h);

    final Class<?>[] intfs = interfaces.clone();
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }

    /*
     * Look up or generate the designated proxy class.
     */
    //获取代理类
    Class<?> cl = getProxyClass0(loader, intfs);

    /*
     * Invoke its constructor with the designated invocation handler.
     */
    try {
        if (sm != null) {
            checkNewProxyPermission(Reflection.getCallerClass(), cl);
        }
        //获取代理类的构造方法
        final Constructor<?> cons = cl.getConstructor(constructorParams);
        final InvocationHandler ih = h;
        if (!Modifier.isPublic(cl.getModifiers())) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    cons.setAccessible(true);
                    return null;
                }
            });
        }
        //创建代理类
        return cons.newInstance(new Object[]{h});
    } catch (IllegalAccessException|InstantiationException e) {
        throw new InternalError(e.toString(), e);
    } catch (InvocationTargetException e) {
        Throwable t = e.getCause();
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else {
            throw new InternalError(t.toString(), t);
        }
    } catch (NoSuchMethodException e) {
        throw new InternalError(e.toString(), e);
    }
}
private static Class<?> getProxyClass0(ClassLoader loader,
                                       Class<?>... interfaces) {
    if (interfaces.length > 65535) {
        throw new IllegalArgumentException("interface limit exceeded");
    }

    // If the proxy class defined by the given loader implementing
    // the given interfaces exists, this will simply return the cached copy;
    // otherwise, it will create the proxy class via the ProxyClassFactory
    // 如果指定类加载器中已经创建了实现指定接口的代理类,则查找缓存,否则通过ProxyClassFactory创建接口的代理类
    return proxyClassCache.get(loader, interfaces);
}

JDK动态代理的实现原理是动态创建代理类并通过指定类加载器加载,然后在创建代理对象时将InvokerHandler对象作为构造参数传入。当调用代理对象时,会调用InvokerHandler.invoke()方法,并最终调用真正业务对象的相应方法。

 

 

7、在MyBatis的日志模块中有一个Jdbc包,它并不是将日志信息通过JDBC保存到数据库中,而是通过JDK动态代理的方式,将JDBC操作通过指定的日志框架打印出来。这个功能通常在开发阶段使用,它可以输出SQL语句、用户传入的绑定参数、SQL语句影响行数等等信息,对调试程序来说是非常重要的。

1b62623ca58b0744c40f6e0e758335b7612.jpg

 

 

转载于:https://my.oschina.net/u/2610056/blog/3028706

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值