Mybatis初始化加载流程————获取接口的动态代理实例

在前面两篇博客中分别介绍了系统是如何将定义的接口Mapper接口注册《Mapper接口的注册》到系统中,系统又是如何绑定接口类名与用来生成接口的MapperFactoryBean之间的关系《接口代理工厂类注册》。

本篇博客将分析系统是如何根据调用时传入的beanName找到接口的动态代理对象的。关于测试代码中的配置文件就不贴出来的,在前面几遍关于mybatis的博客中已经贴出了。
在注册Mapper接口的beanDefinition的时候,beanName为cityMapper,而beanClass为MapperFactoryBean。直接看获取Bean实体的代码:

    AbstractBeanFactory:
    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        final String beanName = transformedBeanName(name);
        Object bean;
        // 在获取Mapper接口的代理实体时,beanName和name均是cityMapper
        // Eagerly check singleton cache for manually registered singletons.
        Object sharedInstance = getSingleton(beanName);
        //这里获取的sharedInstance是不等于空的
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            //直接执行的是下面的方法
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        ......

        // Check if required type matches the type of the actual bean instance.
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }
    AbstractAutowireCapableBeanFactory:
    @Override
    protected Object getObjectForBeanInstance(
            Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
        //添加bean直接的依赖,接口bean没有依赖其他的bean,会直接调用父类的getObjectForBeanInstance方法
        String currentlyCreatedBean = this.currentlyCreatedBean.get();
        if (currentlyCreatedBean != null) {
            registerDependentBean(beanName, currentlyCreatedBean);
        }

        return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
    }
    AbstractBeanFactory:
    protected Object getObjectForBeanInstance(
            Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
        //name所对应的bean实体是一个MapperFactoryBean对象,也就是一个FactoryBean对象。
        //在条件判断中,最终会走到getObjectFromFactoryBean方法中
        // Don't let calling code try to dereference the factory if the bean isn't a factory.
        if (BeanFactoryUtils.isFactoryDereference(name)) {
            if (beanInstance instanceof NullBean) {
                return beanInstance;
            }
            if (!(beanInstance instanceof FactoryBean)) {
                throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
            }
        }

        // Now we have the bean instance, which may be a normal bean or a FactoryBean.
        // If it's a FactoryBean, we use it to create a bean instance, unless the
        // caller actually wants a reference to the factory.
        if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
            return beanInstance;
        }

        Object object = null;
        if (mbd == null) {
            object = getCachedObjectForFactoryBean(beanName);
        }
        if (object == null) {
            // Return bean instance from factory.
            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
            // Caches object obtained from FactoryBean if it is a singleton.
            if (mbd == null && containsBeanDefinition(beanName)) {
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            //通过父类的方法获取Bean实体
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }

调用父类FactoryBeanRegistrySupport中的方法:

    FactoryBeanRegistrySupport:
    protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
        if (factory.isSingleton() && containsSingleton(beanName)) {
            synchronized (getSingletonMutex()) {
                Object object = this.factoryBeanObjectCache.get(beanName);
                //mapper接口的代理还没有生成,这时获取的object为null
                if (object == null) {
                    //执行doGetObjectFromFactoryBean方法
                    object = doGetObjectFromFactoryBean(factory, beanName);
                    // Only post-process and store if not put there already during getObject() call above
                    // (e.g. because of circular reference processing triggered by custom getBean calls)
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    }
                    else {
                        if (shouldPostProcess) {
                            if (isSingletonCurrentlyInCreation(beanName)) {
                                // Temporarily return non-post-processed object, not storing it yet..
                                return object;
                            }
                            beforeSingletonCreation(beanName);
                            try {
                                object = postProcessObjectFromFactoryBean(object, beanName);
                            }
                            catch (Throwable ex) {
                                throw new BeanCreationException(beanName,
                                        "Post-processing of FactoryBean's singleton object failed", ex);
                            }
                            finally {
                                afterSingletonCreation(beanName);
                            }
                        }
                        if (containsSingleton(beanName)) {
                            this.factoryBeanObjectCache.put(beanName, object);
                        }
                    }
                }
                return object;
            }
        }
        else {
            Object object = doGetObjectFromFactoryBean(factory, beanName);
            if (shouldPostProcess) {
                try {
                    object = postProcessObjectFromFactoryBean(object, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                }
            }
            return object;
        }
    }

    private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
            throws BeanCreationException {

        Object object;
        try {
            //没有获取到有效的SecurityManager,直接执行factory.getObject()方法
            if (System.getSecurityManager() != null) {
                AccessControlContext acc = getAccessControlContext();
                try {
                    object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                //这个factory实际上是MapperFactoryBean<com.interfaces.CityMapper>的实体对象
                //接下来会执行MapperFactoryBean中的getObject()方法
                object = factory.getObject();
            }
        }
        catch (FactoryBeanNotInitializedException ex) {
            throw new BeanCurrentlyInCreationException(beanName, ex.toString());
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
        }

        // Do not accept a null value for a FactoryBean that's not fully
        // initialized yet: Many FactoryBeans just return null then.
        if (object == null) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(
                        beanName, "FactoryBean which is currently in creation returned null from getObject");
            }
            object = new NullBean();
        }
        return object;
    }

开始通过MapperFactoryBean中的getObject方法获取相应的实体对象了:

@Override
  public T getObject() throws Exception {
    return getSqlSession().getMapper(this.mapperInterface);
  }

这里会通过getSqlSession方法获取到SqlSessionTemplate对象,内部包含一个sqlSessionFactory对象。SqlSessionFactory的实现类为DefaultSqlSessionFactory。看一下SqlSessionTemplate中的getMapper方法:

  @Override
  public <T> T getMapper(Class<T> type) {
    //调用内部的Configuration对象的getMapper方法
    return getConfiguration().getMapper(type, this);
  }

在Configuration对象中会直接调用MapperRegistry对象的getMapper方法,直接看一下MapperRegistry中的方法:

    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        //这里的T其实就是在java中定义的mapper接口:com.interfaces.CityMapper
        //在刚开始mapper接口注册的时候,根据接口类型创建了一个MapperProxyFactory实例
        //并将实例保存在这个knownMappers集合中了,现在根据type重新取出保存的对象
        final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
        if (mapperProxyFactory == null) {
            throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
        }
        try {
            //调用mapperProxyFactory的newInstance方法,创建一个MapperProxy实例
            return mapperProxyFactory.newInstance(sqlSession);
        } catch (Exception e) {
            throw new BindingException("Error getting mapper instance. Cause: " + e, e);
        }
    }

通过MapperProxyFactory中的newInstance方法创建一个MapperProxy实例对象并且返回给调用方也就是赋值给getBean的结果。

 protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  public T newInstance(SqlSession sqlSession) {
    //新建一个MapperProxy对象,MapperProxy继承并实现了InvocationHandler接口
    //其中mapperInterface是在java中定义的接口:com.interfaces.CityMapper
    //methodCache是根据mapper配置文件解析方法
    final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
    //通过MapperProxy生成一个T的动态代理对象
    return newInstance(mapperProxy);
  }

到此,关于Mybatis的整个加载流程和获取java中接口的动态代理对象的过程就到这里分析结束了,代码中都添加了注释,比较容易理解,就不多说了。

博客中难免会存在错误的地方,如果发现的话,麻烦给我留言帮助我修改错误!

猜你喜欢

转载自blog.csdn.net/u011043551/article/details/80623748
今日推荐