4.Dubbo源码分析----Reference标签的处理

 前面对于Service标签的处理已经说明了Dubbo源码分析----Dubbo的Service注解分析
,现在对Reference标签的处理进行解释。
 对于Reference标签的解析还是按照前面的分析找到ReferenceAnnotationBeanPostProcessor类这个类是dubbo中AnnotationInjectedBeanPostProcessor的子类,而AnnotationInjectedBeanPostProcessor类又继承了spring的AnnotationInjectedBeanPostProcessor类同时实现了MergedBeanDefinitionPostProcessor类。

8438756-a249bfe973b556e9.png
类图

 其中AnnotationInjectedBeanPostProcessor重载了postProcessPropertyValues跟postProcessMergedBeanDefinition方法,对于这两个方法先进行说明。

  • postProcessPropertyValues:这个方法是InstantiationAwareBeanPostProcessor接口中定义的,作用是对实例化之后属性设置之前Bean 的属性值进行修改。调用这个方法的前提是postProcessAfterInstantiation方法返回true,其中postProcessAfterInstantiation方法在InstantiationAwareBeanPostProcessorAdapter默认返回是true。
  • postProcessMergedBeanDefinition:这个方法是在MergedBeanDefinitionPostProcessor类中定义的,作用是在Bean合并之后回调用,也就是Bean属性填充完毕之后。

    所以按顺序,现在先进入到postProcessPropertyValues方法中。
    @Override
    public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
        //获取注入用的元数据
        InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs);
        try {
            //进行注入
            metadata.inject(bean, beanName, pvs);
        } catch (BeanCreationException ex) {
            throw ex;
        } catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Injection of @" + getAnnotationType().getName()
                    + " dependencies is failed", ex);
        }
        return pvs;
    }

postProcessPropertyValues方法主要是对Bean中的属性的获取,其中InjectionMetadata对象是spring中用于管理注入元数据的内部类。现在进入findInjectionMetadata方法

    private InjectionMetadata findInjectionMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
        // Fall back to class name as cache key, for backwards compatibility with custom callers.
        //生成缓存的cacheKey
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
        // Quick check on the concurrent map first, with minimal locking.
        //检查对应的用于诸如用的元数据是否存在缓存
        AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
        //如果元数据是空的,或者元数据缓存中保存的Class对象不是传入的Class对象
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            synchronized (this.injectionMetadataCache) {
                metadata = this.injectionMetadataCache.get(cacheKey);
                //双重检查锁
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    //如果元数据不是null就对其中的属性进行清空
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }
                    try {
                        //创建元数据
                        metadata = buildAnnotatedMetadata(clazz);
                        //放到缓存中进行保存
                        this.injectionMetadataCache.put(cacheKey, metadata);
                    } catch (NoClassDefFoundError err) {
                        throw new IllegalStateException("Failed to introspect object class [" + clazz.getName() +
                                "] for annotation metadata: could not find class that it depends on", err);
                    }
                }
            }
        }
        return metadata;
    }

上面的逻辑也比较简单,就是先检查缓存和比较Class对象判断是不是同一个,如果缓存为空或者缓存的Class对象不是传入的Class对象,就需要先进行缓存的清楚然后创建InjectionMetadata进行保存。现在对元数据的创建进行解析

    private AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata buildAnnotatedMetadata(final Class<?> beanClass) {
        //获取AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement
        Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements = findFieldAnnotationMetadata(beanClass);
        //获取AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement
        Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements = findAnnotatedMethodMetadata(beanClass);
        //上面的两个集合中的对象都是spring中InjectionMetadata类的内部类InjectedElement的继承类用来保存单个元素
        return new AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata(beanClass, fieldElements, methodElements);

    }
    
//-------------

        private List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> findFieldAnnotationMetadata(final Class<?> beanClass) {

        final List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement>();
        // 通过反射的工具类,获取当前beanClass中的所有Field,然后通过实现ReflectionUtils类的内部类FieldCallback的实现,来对字段进行处理
        ReflectionUtils.doWithFields(beanClass, new ReflectionUtils.FieldCallback() {
            @Override
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                //获取field里面的Reference标签
                A annotation = getAnnotation(field, getAnnotationType());
                //检查标签是不是null
                if (annotation != null) {
                    //field不是static类型的
                    if (Modifier.isStatic(field.getModifiers())) {
                        if (logger.isWarnEnabled()) {
                            logger.warn("@" + getAnnotationType().getName() + " is not supported on static fields: " + field);
                        }
                        return;
                    }
                    //创建AnnotatedFieldElement并放到集合中
                    elements.add(new AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement(field, annotation));
                }

            }
        });
        return elements;
    }
//--------------------
    private List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> findAnnotatedMethodMetadata(final Class<?> beanClass) {

        final List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement>();
        //获取到beanClass中所有的Method,然后调用实现的ReflectionUtils.MethodCallback类的doWith方法
        ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
            @Override
            public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
                //寻找method的桥接方法,关于桥接方法这是在Java1.5引入泛型之后,编译器为了向前兼容,生成这个的
                Method bridgedMethod = findBridgedMethod(method);
                //检查是不是可见的桥接方法
                if (!isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                    return;
                }
                //找到方法上的Reference标签
                A annotation = findAnnotation(bridgedMethod, getAnnotationType());
                //如果标签不是bull并且找到beanClass中的具体的方法
                if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) {
                    //方法不能是静态的
                    if (Modifier.isStatic(method.getModifiers())) {
                        if (logger.isWarnEnabled()) {
                            logger.warn("@" + getAnnotationType().getSimpleName() + " annotation is not supported on static methods: " + method);
                        }
                        return;
                    }
                    //需要有参数
                    if (method.getParameterTypes().length == 0) {
                        if (logger.isWarnEnabled()) {
                            logger.warn("@" + getAnnotationType().getSimpleName() + " annotation should only be used on methods with parameters: " +
                                    method);
                        }
                    }
                    //获取beanClass中指定方法的属性
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
                    elements.add(new AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement(method, pd, annotation));
                }
            }
        });
        return elements;
    }

 上面分析了从传入的Bean中获取对应的元数据后保存到InjectionMetadata对象中,现在就是进行注入了。inject方法也是一个模板方法,首先调用的InjectionMetadata的inject然后调用AnnotationInjectedBeanPostProcessor类中的内部类实现的inject方法。

//InjectionMetadata中的inject
    public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        Collection<InjectedElement> checkedElements = this.checkedElements;
        //如果checkedElements为空就使用传入的injectedElements,这里传入的是fieldElements, methodElements两个的组合
        Collection<InjectedElement> elementsToIterate =
                (checkedElements != null ? checkedElements : this.injectedElements);
        if (!elementsToIterate.isEmpty()) {
            //迭代然后调用实现的inject方法
            for (InjectedElement element : elementsToIterate) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Processing injected element of bean '" + beanName + "': " + element);
                }
                element.inject(target, beanName, pvs);
            }
        }
    }
//-----------------------内部类AnnotatedFieldElement跟AnnotatedMethodElement中的方法
    protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
        //获取类型
        Class<?> injectedType = field.getType();
        //获取注入之后的对象
        Object injectedObject = getInjectedObject(annotation, bean, beanName, injectedType, this);
        //如果是私有字段先设置makeAccessible属性
        ReflectionUtils.makeAccessible(field);
        //给Bean对象设置诸如之后的对象
        field.set(bean, injectedObject);
    }
//------getInjectedObject方法
    protected Object getInjectedObject(A annotation, Object bean, String beanName, Class<?> injectedType,
                                       InjectionMetadata.InjectedElement injectedElement) throws Exception {
        //构建缓存对的key
        String cacheKey = buildInjectedObjectCacheKey(annotation, bean, beanName, injectedType, injectedElement);
        //先查询缓存
        Object injectedObject = injectedObjectsCache.get(cacheKey);
        //缓存为null
        if (injectedObject == null) {
            //创建注入之后的对象
            injectedObject = doGetInjectedBean(annotation, bean, beanName, injectedType, injectedElement);
            // Customized inject-object if necessary
            injectedObjectsCache.putIfAbsent(cacheKey, injectedObject);
        }
        return injectedObject;
    }
//------doGetInjectedBean方法
    protected Object doGetInjectedBean(Reference reference, Object bean, String beanName, Class<?> injectedType,
                                       InjectionMetadata.InjectedElement injectedElement) throws Exception {
        //创建应用Bean 的name,根据接口的名称,类型,group等拼接进行闯进
        String referencedBeanName = buildReferencedBeanName(reference, injectedType);
        //如果不存在则创建ReferenceBean对象
        ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referencedBeanName, reference, injectedType, getClassLoader());
        //保存到缓存中
        cacheInjectedReferenceBean(referenceBean, injectedElement);
        //创建reference的代理类
        Object proxy = buildProxy(referencedBeanName, referenceBean, injectedType);
        //返回
        return proxy;
    }

上面就就是对@Reference标签的处理过程,根据获取到的元数据,最后创建一个贴有@Reference标签的接口的代理类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值