zoukankan      html  css  js  c++  java
  • AutowiredAnnotationBeanPostProcessor 的一些思考

    结构: 

    AutowiredAnnotationBeanPostProcessor  类组织结构:

    从类结构可以得知AutowiredAnnotationBeanPostProcessor 依赖的顶层接口为Ordered BeanPostProcessor Aware 这3个接口。

    我们依次看一下这3个顶层接口的作用:

    Ordered :

    是一个可排序的注解标示,用于标示类的一个执行顺序,值最小,表示优先级越高。

    在Ordered 基础上, PriorityOrdered 表示优先的顺序,其执行顺序总是在Ordered 之前。

    我们看一个典型的Ordered 使用调用场景(invokeBeanFactoryPostProcessors),spring 进行BeanFactoryPostProcessors 钩子函数调用:

      1. 无论怎样PriorityOrdered 的优先级是最高的,先是PriorityOrdered 的工厂钩子进行排序调用。

      2.之后的Ordered 的调用,Ordered 进行排序后进行工厂钩子的调用。

      3.没有实现排序接口的工厂钩子调用。

    ///获取所有实现了BeanFactoryPostProcessor 接口的bean                
    String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
            List<String> orderedPostProcessorNames = new ArrayList<>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<>();
            for (String ppName : postProcessorNames) {
                if (processedBeans.contains(ppName)) {
                    // skip - already processed in first phase above
                }
                else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                }
                else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                }
                else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
    
            // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
            sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        //1. 首先无论order 等级多大,先调用PriorityOrdered 的bean        
          invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
            // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
            List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
            for (String postProcessorName : orderedPostProcessorNames) {
                orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            sortPostProcessors(orderedPostProcessors, beanFactory);
        //2.再调用ordered 排序的bean
            invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
            // Finally, invoke all other BeanFactoryPostProcessors.
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
            for (String postProcessorName : nonOrderedPostProcessorNames) {
                nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
        //3.再调用没有实现ordered 注解的bean
            invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

     BeanPostProcessor :

    BeanPostProcessor 是 spring  修改bean 实例以及扩展bean 实例的一个重要工厂钩子类。

    在 BeanPostProcessor 基础上Spring 扩展了如下后置处理器,在bean 的不同阶段发挥着不同作用。

      1 .  BeanPostProcessor : bean 初始化前后调用,此时 bean 已经实例化

      2. InstantiationAwareBeanPostProcessor : 新增 bean 实例化前后调用。

      3. SmartInstantiationAwareBeanPostProcessor :新增预测的bean 的类型,bean 合适的构造器,获取提前暴露的bean 的引用,解决循环引用。

      4.MergedBeanDefinitionPostProcessor ,合并 bean 的信息,在后处理之前提前准备一些缓存一些元数据信息。

     Aware:

    意识到:可以让我们知道容器的一些信息,bean 实例化后进行回调:

    private void invokeAwareMethods(final String beanName, final Object bean) {
            if (bean instanceof Aware) {
                if (bean instanceof BeanNameAware) {
                    ((BeanNameAware) bean).setBeanName(beanName);
                }
                if (bean instanceof BeanClassLoaderAware) {
                    ClassLoader bcl = getBeanClassLoader();
                    if (bcl != null) {
                        ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                    }
                }
                if (bean instanceof BeanFactoryAware) {
                    ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
                }
            }
        }

    再看AutowiredAnnotationBeanPostProcessor :

    说完上看的标注接口后,我们进行完整分析 AutowiredAnnotationBeanPostProcessor :

      1. 初始化的时候,在关注的注入集合里添加@Autowrized @Value @Inject 关注的注解

    public AutowiredAnnotationBeanPostProcessor() {
          //1.添加@Autowrized 注解
            this.autowiredAnnotationTypes.add(Autowired.class);
          //2.添加@value 注解
            this.autowiredAnnotationTypes.add(Value.class);
            try {
        //3.添加@inject 注解
                this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
                        ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
                logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
            }
            catch (ClassNotFoundException ex) {
                // JSR-330 API not available - simply skip.
            }
        }    

     2. 看一下bean 初始化 必经之路 doCreateBean:

      1.调用mergedBean 的merge 方法,进行缓存一些元数据信息;
      2.populationBean 进行实例化bean后的操作,以及属性属性注入的操作
      3.初始化bean
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
                throws BeanCreationException {
    
            // Instantiate the bean.
            BeanWrapper instanceWrapper = null;
            if (mbd.isSingleton()) {
                instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
            }
            if (instanceWrapper == null) {
                instanceWrapper = createBeanInstance(beanName, mbd, args);
            }
            final Object bean = instanceWrapper.getWrappedInstance();
            Class<?> beanType = instanceWrapper.getWrappedClass();
            if (beanType != NullBean.class) {
                mbd.resolvedTargetType = beanType;
            }
            //----------------bean 已经进行了实例化-----------------//
    
            // Allow post-processors to modify the merged bean definition.
            synchronized (mbd.postProcessingLock) {
                if (!mbd.postProcessed) {
                    try {
                        //1.调用 MergedBeanDefinitionPostProcessor的合并bean 操作
                        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                    }
                    catch (Throwable ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Post-processing of merged bean definition failed", ex);
                    }
                    mbd.postProcessed = true;
                }
            }
    
            // Eagerly cache singletons to be able to resolve circular references
            // even when triggered by lifecycle interfaces like BeanFactoryAware.
            boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                    isSingletonCurrentlyInCreation(beanName));
            if (earlySingletonExposure) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Eagerly caching bean '" + beanName +
                            "' to allow for resolving potential circular references");
                }
                addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
            }
    
            // Initialize the bean instance.
            Object exposedObject = bean;
            try {
                //2.传播bean ,进行bean 实例化后的操作
                populateBean(beanName, mbd, instanceWrapper);
                //3.初始化bean ,进行bean 初始化前后的操作
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
            catch (Throwable ex) {
                if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                    throw (BeanCreationException) ex;
                }
                else {
                    throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
                }
            }
    
            if (earlySingletonExposure) {
                Object earlySingletonReference = getSingleton(beanName, false);
                if (earlySingletonReference != null) {
                    if (exposedObject == bean) {
                        exposedObject = earlySingletonReference;
                    }
                    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                        String[] dependentBeans = getDependentBeans(beanName);
                        Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                        for (String dependentBean : dependentBeans) {
                            if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                                actualDependentBeans.add(dependentBean);
                            }
                        }
                        if (!actualDependentBeans.isEmpty()) {
                            throw new BeanCurrentlyInCreationException(beanName,
                                    "Bean with name '" + beanName + "' has been injected into other beans [" +
                                            StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                            "] in its raw version as part of a circular reference, but has eventually been " +
                                            "wrapped. This means that said other beans do not use the final version of the " +
                                            "bean. This is often the result of over-eager type matching - consider using " +
                                            "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                        }
                    }
                }
            }
    
            // Register bean as disposable.
            try {
                registerDisposableBeanIfNecessary(beanName, bean, mbd);
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
            }
    
            return exposedObject;
        }

      我们先看如上第一步, postProcessMergedBeanDefinition mergedBeandefinition 操作:

       findAutowiringMetadata

        public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        //查找需要进行注入的元数据信息
            InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
            metadata.checkConfigMembers(beanDefinition);
        }

        组装注解元数据信息,放入缓存中

     private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
            List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
            Class<?> targetClass = clazz;
    
            do {
                final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
                //field 查询是否有@Autowrized @Value @Inject 注解
                ReflectionUtils.doWithLocalFields(targetClass, field -> {
                    AnnotationAttributes ann = findAutowiredAnnotation(field);
                    if (ann != null) {
                        if (Modifier.isStatic(field.getModifiers())) {
                            if (logger.isInfoEnabled()) {
                                logger.info("Autowired annotation is not supported on static fields: " + field);
                            }
                            return;
                        }
                        //检查required 字段
                        boolean required = determineRequiredStatus(ann);
                        //添加到集合中
                        currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement(field, required));
                    }
                });
    
                ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                    //查看方法上到注解
                    Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                    if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                        return;
                    }
                    AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
                    if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                        if (Modifier.isStatic(method.getModifiers())) {
                            if (logger.isInfoEnabled()) {
                                logger.info("Autowired annotation is not supported on static methods: " + method);
                            }
                            return;
                        }
                        if (method.getParameterCount() == 0) {
                            if (logger.isInfoEnabled()) {
                                logger.info("Autowired annotation should only be used on methods with parameters: " +
                                        method);
                            }
                        }
                        boolean required = determineRequiredStatus(ann);
                        PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                        //添加到集合中
                        currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement(method, required, pd));
                    }
                });
    
                elements.addAll(0, currElements);
                //查看父类字段信息循环获取
                targetClass = targetClass.getSuperclass();
            }
            while (targetClass != null && targetClass != Object.class);
            //返回最终结果
            return new InjectionMetadata(clazz, elements);
        }

    MergedBeanDefinitionPostProcessor 组装完之后,第二步populationBean 操作:
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
            if (bw == null) {
                if (mbd.hasPropertyValues()) {
                    throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
                }
                else {
                    // Skip property population phase for null instance.
                    return;
                }
            }
    
            // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
            // state of the bean before properties are set. This can be used, for example,
            // to support styles of field injection.
            boolean continueWithPropertyPopulation = true;
    
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        //1.实例化之后的操作,调用InstantiationAwareBeanPostProcessor  的 postProcessAfterInstantiation
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            continueWithPropertyPopulation = false;
                            break;
                        }
                    }
                }
            }
    
            if (!continueWithPropertyPopulation) {
                return;
            }
    
            PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
            //2.根据 autowrized 类型,将需要注入的信息放入 PropertyValues 集合中
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
                MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
                // Add property values based on autowire by name if applicable.
                if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
                    autowireByName(beanName, mbd, bw, newPvs);
                }
                // Add property values based on autowire by type if applicable.
                if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
                    autowireByType(beanName, mbd, bw, newPvs);
                }
                pvs = newPvs;
            }
    
            boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
            boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    
            PropertyDescriptor[] filteredPds = null;
            if (hasInstAwareBpps) {
                if (pvs == null) {
                    pvs = mbd.getPropertyValues();
                }
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        //3.进行属性注入的操作
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            if (filteredPds == null) {
                                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                            }
                            pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                            if (pvsToUse == null) {
                                return;
                            }
                        }
                        pvs = pvsToUse;
                    }
                }
            }
            if (needsDepCheck) {
                if (filteredPds == null) {
                    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
            //4.bean set 方法的注入,一般在设置了beanDefinition 的PropertyValues的时候会调用这个方法,与第2步的方法合用
            if (pvs != null) {
                applyPropertyValues(beanName, mbd, bw, pvs);
            }
        }

    第3步,初始化bean:

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    //调用aware 方法
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }, getAccessControlContext());
            }
            else {
                invokeAwareMethods(beanName, bean);
            }
    
            Object wrappedBean = bean;
    //beanPost 初始化前调用
            if (mbd == null || !mbd.isSynthetic()) {
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
    
            try {
        //调用初始化方法 InitializingBean 的afterpropertiesSet() 以及初始化方法
                invokeInitMethods(beanName, wrappedBean, mbd);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(
                        (mbd != null ? mbd.getResourceDescription() : null),
                        beanName, "Invocation of init method failed", ex);
            }
    //beanPostProcessor 初始化后调用
            if (mbd == null || !mbd.isSynthetic()) {
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }
    
            return wrappedBean;
        }

    总结:

    看完 AutowiredAnnotationBeanPostProcessor 的实现,我们想一下,比如nacos 注入属性操作的一些标签注解,在底层都会有相对用的BeanPostProcessor 对其注解进行解释注入操作,我们甚至可以针对这个特性根据业务实现自己的属性注入操作。

  • 相关阅读:
    109 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 03 新增功能及实现 05 问题解析--通过一个方法完成学生和专业的双向关联
    108 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 03 新增功能及实现 04 问题解析--数组未实例化造成的空指针异常
    107 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 03 新增功能及实现 03 编写方法完成学生个数统计功能
    106 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 03 新增功能及实现 02 新增属性完成学生信息存储
    105 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 03 新增功能及实现 01 新增需求及分析
    session与cookie的区别和联系
    session和cookie的区别
    Web服务器主动推送技术
    webSocket的场景应用
    TCP、Http和Socket 优劣比较
  • 原文地址:https://www.cnblogs.com/iscys/p/13170689.html
Copyright © 2011-2022 走看看