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 对其注解进行解释注入操作,我们甚至可以针对这个特性根据业务实现自己的属性注入操作。

  • 相关阅读:
    开发报表的先进工具
    强大的报表前端展现功能
    管理驾驶舱监控大屏展现
    换乘算法【转】
    提交中文数据乱码问题总结
    重定向
    容易遗漏的
    jsp基础语法【转】
    说说Java NIO【转】
    Java读取大文件的操作【转】
  • 原文地址:https://www.cnblogs.com/iscys/p/13170689.html
Copyright © 2011-2022 走看看