• Spring源码分析(八)依赖注入源码解析1:autowire自动注入 和 @Autowired注入


    Spring中到底有几种依赖注入的方式?

    首先分两种:

    1. 手动注入
    2. 自动注入

    手动注入

    在XML中定义Bean时,就是手动注入,因为是程序员手动给某个属性指定了值

    <bean name="userService" class="com.luban.service.UserService">
    	<property name="orderService" ref="orderService"/>
    bean>
    
    • 1
    • 2
    • 3

    上面这种底层是通过set方法进行注入。

    <bean name="userService" class="com.luban.service.UserService">
    	<constructor-arg index="0" ref="orderService"/>
    bean>
    
    • 1
    • 2
    • 3

    上面这种底层是通过构造方法进行注入。

    所以手动注入的底层也就是分为两种:

    1. set方法注入
    2. 构造方法注入

    自动注入

    自动注入也分为两种:

    1. XML的autowire自动注入
    2. @Autowired注解的自动注入

    接下来开始源码分析

    入口 - 属性填充阶段

    直接看Bean生命周期的属性填充阶段:
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {...}
    
        // 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.
        // 实例化之后,属性填充之前
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {...}
    
        //属性值,用来通过set方法注入的值
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    
        //1. autowire自动注入
        int resolvedAutowireMode = mbd.getResolvedAutowireMode();
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            // Add property values based on autowire by name if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
                //autowire根据Name自动注入(其实只是收集注入值到newPvs中)
                autowireByName(beanName, mbd, bw, newPvs);
            }
            // Add property values based on autowire by type if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                //autowire根据Type自动注入(其实只是收集注入值到newPvs中)
                autowireByType(beanName, mbd, bw, newPvs);
            }
            //核心,ByName或者ByType找到属性对应的值以后,就会放到pvs中
            pvs = newPvs;
        }
    
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    	
        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            //2.@Autowired注解注入
            for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
                //默认提供的实现里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法直接给对象中的属性赋值
                //	AutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了
                //	AutowiredAnnotationBeanPostProcessor会处理@Autowired、@Value、 @Inject 注解
                //	CommonAnnotationBeanPostProcessor会处理@Resource注解
                PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    if (filteredPds == null) {
                        //获取筛选后的propertydescriptor,属性描述器集合(排除被忽略的依赖项类型 或 在被忽略的依赖项接口上 定义的属性)
                        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }
                    //过时了,在工厂将给定的属性值应用到给定的bean之前,对它们进行后处理。
                    //允许检查是否满足了所有依赖项,例如基于bean属性设置器上的“Required”注解。
                    //	默认实现RequiredAnnotationBeanPostProcessor中,支持给"setXXX"方法加上@Required注解
                    //	标记为“必需的”,简单来说,就是要求pvs属性值中一定要存在 给@Required标记的set方法注入的值  
                    pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                pvs = pvsToUse;
            }
        }
    
        //依赖项检查,确保所有公开的属性都已设置
        //依赖项检查可以是对象引用、“简单”属性(原语和String)或所有(两者都是)
        if (needsDepCheck) {
            if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    
        if (pvs != null) {
            //3.属性赋值(把pvs里的属性值给bean进行赋值!!!!!)
            //autowire自动注入,其实只是收集注入的值,放到pvs中,最终赋值的动作还是在这里!!
            //PropertyValues中的值优先级最高
            //	如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值,覆盖@Autowired的
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    1. autowire自动注入

    xml中可以通过autowire属性设置:

    <bean id="user" class="com.yth.service.User" autowire="byName"/>
    
    • 1

    @Bean方式也行

    @ComponentScan("com.yth")
    public class AppConfig {
        @Bean(autowire = Autowire.BY_TYPE)
        public OrderService orderService() {
            return new OrderService();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ByName

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireByName

    protected void autowireByName(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    	//1.1 获取当前bean中能进行自动注入的属性名
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        //遍历每个属性名,并去获取Bean对象,并设置到pvs中
        for (String propertyName : propertyNames) {
            if (containsBean(propertyName)) {
            	//直接根据beanName获取Bean
                Object bean = getBean(propertyName);
                //这里把propertyName对应的属性值保存到了MutablePropertyValues
                //暂时只是记录了一下,还没有赋值
                pvs.add(propertyName, bean);
                //记录一下propertyName对应的Bean被beanName给依赖了
                //(之前讲DependsOn注解也走过这个方法)
                registerDependentBean(propertyName, beanName);
                if (logger.isTraceEnabled()) {...}
            }
            else {...}
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 直接根据beanName获取Bean
    • 只做了记录,还没有进行赋值的动作!!

    ByType

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireByType

    protected void autowireByType(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    
        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {...}
    
        Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
        //1.1 获取当前bean中能进行自动注入的属性名
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            try {
                PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
                // Don't try autowiring by type for type Object: never makes sense,
                // even if it technically is an unsatisfied, non-simple property.
                // 如果需要注入的属性类型是Object类型没有意义(注入的时候发现类型是Object这咋注入)
                if (Object.class != pd.getPropertyType()) {
                    MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                    // Do not allow eager init for type matching in case of a prioritized post-processor.
                    // 在优先级后处理器的情况下,不允许为了类型匹配而立即初始化。
                    //	为什么不允许,因为我自己是PriorityOrdered,是优先级最高的,不能有比我创建得更早的
                    //	PriorityOrdered:Ordered接口的扩展,表示优先级排序:priorityorordered对象总是应用在普通Ordered对象之前,而不管其顺序值如何。
                    // 	eager表示立即初始化,表示在根据类型查找Bean时,允不允许进行Bean的创建,如果当前Bean实现了PriorityOrdered则不允许
                    boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
    
                    //依赖注入描述器
                    DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                    
                    // 1.2 根据类型找到结果(@Autowired注解也是用的这个方法,非常重要和复杂)
                    // 这个方法下一节再讲,很复杂!!
                    Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
                    if (autowiredArgument != null) {
                        //和ByName同理,只是记录
                        pvs.add(propertyName, autowiredArgument);
                    }
                    //因为有可能注入的时候是个List,所以这里autowiredBeanNames是个集合
                    for (String autowiredBeanName : autowiredBeanNames) {
                        //记录一下autowiredBeanName对应的Bean被beanName给依赖了
                        registerDependentBean(autowiredBeanName, beanName);
                        if (logger.isTraceEnabled()) {...}
                    }
                    autowiredBeanNames.clear();
                }
            }
            catch (BeansException ex) {...}
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    同理,只做了记录,还没有进行赋值的动作!!

    1.1 获取当前bean中能进行自动注入的属性名

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#unsatisfiedNonSimpleProperties

    protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
        Set<String> result = new TreeSet<>();
        PropertyValues pvs = mbd.getPropertyValues();
        //获取当前对象中,所有符合javaBean定义的有get/set方法的属性的属性描述器
        //	底层其实只会判断get/set方法,有get/set方法就会解析成一个属性描述器,但是要求get/set方法满足一定的条件
        //  条件简单理解总结就是:
        //		get方法的定义是: 方法参数个数为0个,并且方法名字以"get"开头 
    	//						或者 方法名字以"is"开头并 且方法的返回类型为boolean
    	//		set方法的定义是:方法参数个数为1个,方法名字以"set"开头,且方法返回类型为 void
        PropertyDescriptor[] pds = bw.getPropertyDescriptors();
    
        //什么样的属性能进行自动注入?
        //1.该属性有对应的set方法	pd.getWriteMethod() != null
        //2.该属性类型没有在ignoredDependencyTypes中
        //3.如果该属性对应的set方法是实现的某个接口中所定义的,那么接口没有在ignoredDependencyInterfaces中 
        //4.getPropertyValues中不能包含该属性 !pvs.contains(pd.getName())
        //5.属性类型不是简单类型,比如int、Integer、int[]
        for (PropertyDescriptor pd : pds) {
            if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
                    !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
                result.add(pd.getName());
            }
        }
        return StringUtils.toStringArray(result);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    什么样的属性能进行自动注入?

    1. 该属性有对应的set方法 pd.getWriteMethod() != null
    2. 该属性类型没有在ignoredDependencyTypes中
    3. 如果该属性对应的set方法是实现的某个接口中所定义的,那么接口没有在ignoredDependencyInterfaces中
    4. getPropertyValues中不能包含该属性 !pvs.contains(pd.getName())
    5. 属性类型不是简单类型,比如int、Integer、int[]

    [2,3]:
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#isExcludedFromDependencyCheck

    protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
        //AutowireUtils.isExcludedFromDependencyCheck:排除了CGLIB定义的属性
        //ignoredDependencyTypes:依赖项检查和自动装配时要忽略的依赖项类型,是一个类对象集合:例如,字符串。默认是没有的。
        //ignoredDependencyInterfaces:依赖项检查和自动装配时要忽略的依赖项接口,是一个类对象的集合。默认情况下,只有BeanFactory接口被忽略。
        return (AutowireUtils.isExcludedFromDependencyCheck(pd) ||
                this.ignoredDependencyTypes.contains(pd.getPropertyType()) ||
                AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    [4]:比如我们可以在Bean生命周期的 BeanDefinition后置处理阶段,给PropertyValues赋值,这样相同的属性名称,在当前流程中就会跳过该属性,肯定程序员自定义的优先级高喽。
    在这里插入图片描述

    [5]:判断是否是简单类型
    org.springframework.beans.BeanUtils#isSimpleProperty

    public static boolean isSimpleProperty(Class<?> type) {
        Assert.notNull(type, "'type' must not be null");
        return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType()));
    }
    
    public static boolean isSimpleValueType(Class<?> type) {
        //isPrimitiveOrWrapper方法中,void/Void也会返回true,所以这里一开始就单独判断了一下。
        return (Void.class != type && void.class != type &&
                //以下这些都属于简单类型
                //isPrimitiveOrWrapper:检查给定的类是否代表
            	//		一个原语(即boolean、byte、char、short、int、long、float或double)、void
            	//		或这些类型的包装器(即Boolean、Byte, Character, Short, Integer, Long, Float, Double, or Void)。
                (ClassUtils.isPrimitiveOrWrapper(type) ||
                Enum.class.isAssignableFrom(type) ||
                CharSequence.class.isAssignableFrom(type) ||
                Number.class.isAssignableFrom(type) ||
                Date.class.isAssignableFrom(type) ||
                Temporal.class.isAssignableFrom(type) ||
                URI.class == type ||
                URL.class == type ||
                Locale.class == type ||
                Class.class == type));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    注意:

    • isPrimitiveOrWrapper方法中,void/Void也会返回true,所以在isSimpleValueType中一开始会单独判断。
    • Enum、CharSequence、Number…这些都认为是简单类型
    • autowire自动注入会忽略简单数据类型,但是@Autowire不会忽略。

    PropertyDescriptor

    属性描述器,java.beans提供的。 (java.beans.PropertyDescriptor)
    java规范中,认为Bean的属性要有get和set方法
    在这里插入图片描述

    我们找下PropertyDescriptor是怎么生成的:

    org.springframework.beans.BeanWrapper#getPropertyDescriptors    //接口
    org.springframework.beans.BeanWrapperImpl#getPropertyDescriptors
    org.springframework.beans.BeanWrapperImpl#getCachedIntrospectionResults
    org.springframework.beans.CachedIntrospectionResults#forClass
    org.springframework.beans.CachedIntrospectionResults#CachedIntrospectionResults	//构造方法
    org.springframework.beans.CachedIntrospectionResults#getBeanInfo(java.lang.Class<?>)
    org.springframework.beans.BeanInfoFactory#getBeanInfo	//接口
    org.springframework.beans.ExtendedBeanInfoFactory#getBeanInfo
    java.beans.Introspector#getBeanInfo(java.lang.Class<?>) //从这里开始就是jdk提供的方法了
    java.beans.Introspector#getBeanInfo()
    java.beans.Introspector#getTargetPropertyInfo
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    java.beans.Introspector#getTargetPropertyInfo

    private PropertyDescriptor[] getTargetPropertyInfo() {
    
        // Check if the bean has its own BeanInfo that will provide
        // explicit information.
        // 检查bean是否有自己的BeanInfo来提供显式信息。 (支持自定义BeanInfo)
        PropertyDescriptor[] explicitProperties = null;
        if (explicitBeanInfo != null) {...}
    
        //检查父类有没有自定义的BeanInfo来提供显式信息
        if (explicitProperties == null && superBeanInfo != null) {...}
    	
        //检查额外的类信息(也是通过explicitBeanInfo,自定义BeanInfo提供的)
        for (int i = 0; i < additionalBeanInfo.length; i++) {...}
        
    	//explicitProperties是自定义的,如果没有自定义指定,会利用反射解析获取属性信息
        if (explicitProperties != null) {
            // Add the explicit BeanInfo data to our results.
            addPropertyDescriptors(explicitProperties);
        } else {
            // 如果没有自定义指定,会利用反射解析获取属性信息
        	
            // Apply some reflection to the current class.
    		// 否则对当前类应用反射进行解析
            // First get an array of all the public methods at this level
            // 获取所有public方法
            Method methodList[] = getPublicDeclaredMethods(beanClass);
    
            // Now analyze each method.
            for (int i = 0; i < methodList.length; i++) {
                Method method = methodList[i];
                if (method == null) {
                    continue;
                }
                // skip static methods.
                // 跳过静态方法
                int mods = method.getModifiers();
                if (Modifier.isStatic(mods)) {
                    continue;
                }
                //方法名
                String name = method.getName();
                //方法入参
                Class<?>[] argTypes = method.getParameterTypes();
                //方法返回值
                Class<?> resultType = method.getReturnType();
                int argCount = argTypes.length;
                PropertyDescriptor pd = null;
            	//方法名长度小于3且不是is开头,肯定不属于规范的get/set方法
                if (name.length() <= 3 && !name.startsWith(IS_PREFIX)) {
                    // Optimization. Don't bother with invalid propertyNames.
                    continue;
                }
    
                try {
                	//方法入参个数0的情况
                    if (argCount == 0) {
                        if (name.startsWith(GET_PREFIX)) {
                            // Simple getter
                            pd = new PropertyDescriptor(this.beanClass, name.substring(3), method, null);
                        } else if (resultType == boolean.class && name.startsWith(IS_PREFIX)) {
                            // Boolean getter
                            pd = new PropertyDescriptor(this.beanClass, name.substring(2), method, null);
                        }
                    } 
                    //方法入参个数1的情况
                    else if (argCount == 1) {
                        if (int.class.equals(argTypes[0]) && name.startsWith(GET_PREFIX)) {
                            pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, method, null);
                        } else if (void.class.equals(resultType) && name.startsWith(SET_PREFIX)) {
                            // Simple setter
                            pd = new PropertyDescriptor(this.beanClass, name.substring(3), null, method);
                            if (throwsException(method, PropertyVetoException.class)) {
                                pd.setConstrained(true);
                            }
                        }
                    }
                    //方法入参个数2的情况
                    else if (argCount == 2) {
                            if (void.class.equals(resultType) && int.class.equals(argTypes[0]) && name.startsWith(SET_PREFIX)) {
                            pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, null, method);
                            if (throwsException(method, PropertyVetoException.class)) {
                                pd.setConstrained(true);
                            }
                        }
                    }
                } catch (IntrospectionException ex) {...}
    
                if (pd != null) {
                    // If this class or one of its base classes is a PropertyChange
                    // source, then we assume that any properties we discover are "bound".
                    if (propertyChangeSource) {...}
                    addPropertyDescriptor(pd);
                }
            }
        }
        //通过合并属性描述符列表来填充属性描述符表。(属性分类合并)
        //	按照java规范来说,一个属性至少有get/set两个方法,对于一个属性描述器
        processPropertyDescriptors();
    
        // Allocate and populate the result array.
        PropertyDescriptor result[] =
                properties.values().toArray(new PropertyDescriptor[properties.size()]);
    
        // Set the default index.
        if (defaultPropertyName != null) {...}
    
        return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108

    判断方法入参个数:

    • 0个的情况:
      • 方法名以"get"开头认为是get方法
      • 方法名以"is"开头,且返回值为boolean类型认为是get方法
    • 1个的情况:
      • 入参类型为int,且方法名以"get"开头认为是get方法(IndexedPropertyDescriptor)
      • 返回值类型为void,且方法名以"set"开头认为是set方法
    • 2个的情况:
      • 返回值类型为void,第一个入参类型为int,且方法名以"set"开头认为是set方法(IndexedPropertyDescriptor)

    IndexedPropertyDescriptor:

    • 描述了一个类似数组的属性,它具有索引读和/或索引写方法来访问数组的特定元素。
    • 索引属性还可以提供简单的非索引读和写方法。如果存在,则读写. 索引read方法返回的类型 的数组。

    简单概括就是:

    • get方法的定义是: 方法参数个数为0个,并且方法名字以"get"开头

      或者 方法名字以"is"开头并 且方法的返回类型为boolean

    • set方法的定义是:方法参数个数为1个,方法名字以"set"开头,且方法返回类型为 void

    所以getClass方法也被解析成了一个属性PropertyDescriptor
    在这里插入图片描述

    1.2 根据类型找结果

    @Autowired注解也是用的这个方法,非常重要和复杂
    这个方法下一节再讲,很复杂!!

    2. @Autowired注解注入

    注解注入的实现是依赖BeanPostProcessor的扩展机制实现的,即InstantiationAwareBeanPostProcessor

    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        //2.@Autowired注解注入
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            //默认提供的实现里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法直接给对象中的属性赋值
            //	AutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了
            //	AutowiredAnnotationBeanPostProcessor会处理@Autowired、@Value、 @Inject 注解
            //	CommonAnnotationBeanPostProcessor会处理@Resource注解
            PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {...}
            pvs = pvsToUse;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    InstantiationAwareBeanPostProcessor的实现中:

    • AutowiredAnnotationBeanPostProcessor会处理@Autowired、@Value、 @Inject 注解
    • CommonAnnotationBeanPostProcessor会处理@Resource注解

    我们先分析AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor相对简单,逻辑也和@Autowired的差不多。

    AutowiredAnnotationBeanPostProcessor

    AutowiredAnnotationBeanPostProcessors实现了两个接口:
    在这里插入图片描述

    其中SmartInstantiationAwareBeanPostProcessor继承于InstantiationAwareBeanPostProcessor,比它更强大:
    在这里插入图片描述


    以后讲,先不管。

    看到它实现了两个接口:InstantiationAwareBeanPostProcessor(SmartInstantiationAwareBeanPostProcessor),MergedBeanDefinitionPostProcessor

    按照Bean的生命周期流程的执行顺序:

    • 我们先看MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition方法的实现
    • 再看InstantiationAwareBeanPostProcessor.postProcessProperties方法的实现

    在这里插入图片描述

    postProcessMergedBeanDefinition:解析注入点并缓存
    postProcessProperties:基于注入点属性注入

    2.1 解析注入点并缓存

    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
    }
    
    • 1
    • 2
    • 3
    • 4
    private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
        // Fall back to class name as cache key, for backwards compatibility with custom callers.
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
        // Quick check on the concurrent map first, with minimal locking.
        // 首先快速检查并发map,尽量减少锁的范围。
        
        // InjectionMetadata:封装了当前类中所有的注入点
        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            //同步锁+双重检查
            synchronized (this.injectionMetadataCache) {
                metadata = this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }
                    //解析注入点并缓存(被@Autowired标记的属性、方法..)
                    metadata = buildAutowiringMetadata(clazz);
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }
        return metadata;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    解析注入点:

    private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
        //a. 判断当前类是否需要查找注入点(包路径是java.开头的类不需要找注入点)
        //比如如果一个Bean的类型是String...那么则根本不需要进行依赖注入
        if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
            //不是候选类,直接返回
            return InjectionMetadata.EMPTY;
        }
    
        List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
        Class<?> targetClass = clazz;
    
        do {
            final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
        	//遍历targetClass中所有的field
            ReflectionUtils.doWithLocalFields(targetClass, field -> {
                //b. field上是否存在@Autowired、@Value、@Inject其中的一个
                MergedAnnotation<?> ann = findAutowiredAnnotation(field);
                if (ann != null) {
                    //static field不是注入点,不会进行自动注入
                    //e.因为静态属性是属于类的,而不是属于对象的。
                    if (Modifier.isStatic(field.getModifiers())) {
                        if (logger.isInfoEnabled()) {...}
                        return;
                    }
                    //c.判断是否要必须注入,针对@Autowired的required属性。
                    boolean required = determineRequiredStatus(ann);
                    //构造字段注入点
                    currElements.add(new AutowiredFieldElement(field, required));
                }
            });
    
            //遍历targetClass中所有的Method
            ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                //d.找到所提供的桥接方法的原始方法
                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                //比较桥接方法和它桥接的方法的特征。如果参数和返回类型相同,则它是Java 6中引入的“可见性”桥接方法
                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                    //“可见性”桥接方法也会过滤
                    return;
                }
                //b. 判断method上是否存在@Autowired、@Value、@Inject其中的一个
                MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
                if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                    //e.static method不是注入点,不会进行自动注入
                    if (Modifier.isStatic(method.getModifiers())) {
                        if (logger.isInfoEnabled()) {...}
                        return;
                    }
                    //set方法最好有入参,做个日志提示(没有参数、1个参数、多个参数都可以)
                    //就算@Autowired标记的方法没有入参,Spring也会去执行,只是不会去找参数类型对应的实例
                    if (method.getParameterCount() == 0) {...}
                    //c.判断是否要必须注入,针对@Autowired的required属性。
                    boolean required = determineRequiredStatus(ann);
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    //构造方法注入点
                    currElements.add(new AutowiredMethodElement(method, required, pd));
                }
            });
    
            elements.addAll(0, currElements);
            targetClass = targetClass.getSuperclass();
        }
        //do while循环,递归处理父类
        while (targetClass != null && targetClass != Object.class);
    
        //将所有注入点整体封装成一个对象返回
        return InjectionMetadata.forElements(elements, clazz);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    a. 判断当前类是否需要查找注入点

    org.springframework.core.annotation.AnnotationUtils#isCandidateClass(java.lang.Class, java.util.Collection>)

    autowiredAnnotationTypes的值:
    在这里插入图片描述

    public static boolean isCandidateClass(Class<?> clazz, Collection<Class<? extends Annotation>> annotationTypes) {
        //annotationTypes此时就是@Autowired、@Value、@Inject
        for (Class<? extends Annotation> annotationType : annotationTypes) {
            if (isCandidateClass(clazz, annotationType)) {
                return true;
            }
        }
        return false;
    }
    
    public static boolean isCandidateClass(Class<?> clazz, Class<? extends Annotation> annotationType) {
        return isCandidateClass(clazz, annotationType.getName());
    }
    
    public static boolean isCandidateClass(Class<?> clazz, String annotationName) {
        //注解名字是java.开头的,代表需要查找注入点
        if (annotationName.startsWith("java.")) {
            return true;
        }
        //什么情况下不需要找注入点呢?主要看这:
        if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(clazz)) {
            return false;
        }
        //默认true,大部分情况下类都是要找注入点的
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    org.springframework.core.annotation.AnnotationsScanner#hasPlainJavaAnnotationsOnly(java.lang.Class)

    static boolean hasPlainJavaAnnotationsOnly(Class<?> type) {
        //java.开头的类不需要找注入点
        return (type.getName().startsWith("java.") || type == Ordered.class);
    }
    
    • 1
    • 2
    • 3
    • 4

    b. 判断field/method上是否存在@Autowired、@Value、@Inject其中的一个

    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiredAnnotation

    private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
        //获取指定元素上的所有注解和元注解。(默认不包括任何继承的注解)
        MergedAnnotations annotations = MergedAnnotations.from(ao);
        for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
            MergedAnnotation<?> annotation = annotations.get(type);
            if (annotation.isPresent()) {
                return annotation;
            }
        }
        return null;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其中autowiredAnnotationTypes值在构造函数里初始化了:@Autowired、@Value、@Inject
    在这里插入图片描述

    c. 判断是否要必须注入,针对@Autowired的required属性

    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineRequiredStatus(org.springframework.core.annotation.MergedAnnotation)

    protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
        //调用MergedAnnotation.asMap方法,传入lambda表达式的一个对象,生成AnnotationAttributes对象
        return determineRequiredStatus(ann.<AnnotationAttributes> asMap(
            mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
    }
    
    protected boolean determineRequiredStatus(AnnotationAttributes ann) {
        //requiredParameterName="required"
        //requiredParameterValue=true
        //判断注解上是否包含required属性,并且是否为true
        return (!ann.containsKey(this.requiredParameterName) ||
                this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    d. 找到所提供的桥接方法的原始方法

    什么情况下会有桥接方法?

    public interface UserInterface<T> {
        void setOrderService(T t);
    }
    
    • 1
    • 2
    • 3
    @Component
    public class UserService implements UserInterface<OrderService> {
    
        private OrderService orderService;
    
        @Override
        @Autowired
        public void setOrderService(OrderService orderService) {
            this.orderService = orderService;
        }
    
        public void test() {
            System.out.println("test123");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    此时这段代码应该只有一个注入点,但是我们看下UserService对应的字节码:
    在这里插入图片描述

    可以看到在UserSerivce的字节码中有两个setOrderService方法:

    1. public setOrderService(Lcom/zhouyu/service/OrderService;)V
    2. public synthetic bridge setOrderService(Ljava/lang/Object;)V

    并且都是存在@Autowired注解的。

    java字节码层面针对泛型方法,就会特殊处理生成一个synthetic bridge的方法
    java泛型,翻译成字节码,底层其实就是一个Object类型。(泛型、桥接方法、泛型擦除)

    简单通过反射就会拿到两个方法,所以在Spring中需要处理这种情况,当遍历到桥接方法时,得找到原方法。

    e. static的字段或方法为什么不支持

    Demo演示:

    @Component
    @Scope("prototype")
    public class OrderService {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    @Component
    @Scope("prototype")
    public class UserService  {
    
    	@Autowired
    	private static OrderService orderService;
    
    	public void test() {
    		System.out.println("test123");
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    看上面代码,UserService和OrderService都是原型Bean,假设Spring支持static字段进行自动注入,那么现在调用两次

    1. UserService userService1 = context.getBean(“userService”)
    2. UserService userService2 = context.getBean(“userService”)

    问此时,userService1的orderService值是什么?还是它自己注入的值吗?
    答案是不是,一旦userService2 创建好了之后,static orderService字段的值就发生了修改了,从而出现bug。

    2.2 基于注入点属性注入

    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties

    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        //找注入点(所有被@Autowired注解了的Field或Method)
        //findAutowiringMetadata方法在上一步,BeanDefinition的后置流程中已经执行过了,所以此时直接从缓存拿了
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        try {
            //注入
            metadata.inject(bean, beanName, pvs);
        }
        catch (BeanCreationException ex) {...}
        catch (Throwable ex) {...}
        return pvs;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    org.springframework.beans.factory.annotation.InjectionMetadata#inject

    public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        Collection<InjectedElement> checkedElements = this.checkedElements;
        Collection<InjectedElement> elementsToIterate =
                (checkedElements != null ? checkedElements : this.injectedElements);
        if (!elementsToIterate.isEmpty()) {
            //遍历每个注入点,进行依赖注入
            for (InjectedElement element : elementsToIterate) {
                element.inject(target, beanName, pvs);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    方法和字段注入点对应的类型:
    在这里插入图片描述

    a. 字段注入

    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject

        protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            Field field = (Field) this.member;
            Object value;
            //缓存,一开始肯定没有缓存
            if (this.cached) {...}
            else {
                //根据field从BeanFactory中查到匹配的Bean对象
                value = resolveFieldValue(field, bean, beanName);
            }
            //反射给field赋值
            if (value != null) {
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    resolveFieldValue:关于怎么找的,比较复杂,下一节再说。

    b.方法注入

    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject

    protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        //如果pvs中已经有当前注入点的值了,则跳过注入(autowire注入、set方法注入的优先级更高)
        if (checkPropertySkipping(pvs)) {
            return;
        }
        Method method = (Method) this.member;
        Object[] arguments;
        //缓存,一开始肯定没有缓存
        if (this.cached) {...}
        else {
            //根据方法信息找值,@Autowired注解标记的方法允许多个参数
            //怎么找下一节再说。
            arguments = resolveMethodArguments(method, bean, beanName);
        }
        if (arguments != null) {
            try {
                //反射调方法
                ReflectionUtils.makeAccessible(method);
                method.invoke(bean, arguments);
            }
            catch (InvocationTargetException ex) {...}
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    3. PropertyValues手动注入

    把pvs(PropertyValues属性)里的属性值给bean进行赋值!

    • 如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值,覆盖@Autowired
    • 通过pvs里的属性值给bean进行赋值,需要提供写方法才生效

    PropertyValues怎么设置?

    • pvs里的属性值可以利用autowire自动注入的方式收集
    • 也可以手动设置(优先级最高),比如可以通过以下方式设置让属性赋值生效:
      在这里插入图片描述

    applyPropertyValues 方法的主要逻辑是遍历 bd.propertyValues 中的 PropertyValue 属性,根据引用类型提取出对象实例,再将这个对象实例转换成可以直接注入的实例。

    1. 解析对象:valueResolver.resolveValueIfNecessary(pv, originalValue) 将 pv.value 解析成实例对象。
    2. 类型转换:convertForProperty(resolvedValue, propertyName, bw, converter) 将 resolvedValue 转换成可直接进行类型注入的类型。
    3. 依赖注入: bw.setPropertyValues(mpvs) 将解析后的属性注入到 bw 实例中
    4. 结果缓存:Spring 会将 valueResolver 和 converter 解析后的最终对象缓存到 pv 中,提高效率。如果全部 pv 都不需要重新解析,则设置 mpvs.converted=true。

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues

    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if (pvs.isEmpty()) {
            return;
        }
    
        if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {...}
    
        MutablePropertyValues mpvs = null;
        List<PropertyValue> original;
    	//1.获取List,如果已经解析过,则直接注入后返回
        
        //通常来说,默认实现就是MutablePropertyValues
        if (pvs instanceof MutablePropertyValues) {
            mpvs = (MutablePropertyValues) pvs;
            //isConverted:返回该holder是否只包含转换后的值(true),或者值是否仍然需要转换(false)。
            //MutablePropertyValues已经解析,直接注入,在方法解析后会缓存已经解析的PropertyValue
            if (mpvs.isConverted()) {
                // Shortcut: use the pre-converted values as-is.
                try {
                    // BeanWrapper属性注入
                    bw.setPropertyValues(mpvs);
                    return;
                }
                catch (BeansException ex) {...}
            }
            original = mpvs.getPropertyValueList();
        }
        else {
            original = Arrays.asList(pvs.getPropertyValues());
        }
    
        //类型转换器
        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }
        //BeanDefinitionValueResolver:解析器,用于解析PropertyValue,如间接引用替换成直接对象
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
    
    
        //2.逐个解析、转换PropertyValue
        
        // Create a deep copy, resolving any references for values.
        // 创建一个深度拷贝,解析值的任何引用。
        List<PropertyValue> deepCopy = new ArrayList<>(original.size());
        
        boolean resolveNecessary = false;
        for (PropertyValue pv : original) {
            if (pv.isConverted()) {
                //已经类型转换过了
                deepCopy.add(pv);
            }
            else {
                String propertyName = pv.getName();
                Object originalValue = pv.getValue();
                //标记位,实际使用resolveDependency方法查找依赖注入的对象
                if (originalValue == AutowiredPropertyMarker.INSTANCE) {
                    //必须要提供写方法
                    Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
                    if (writeMethod == null) {
                        throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
                    }
                    //构建一个属性描述器
                    originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
                }
    
                //2.1 解析对象
                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
    
                //2.2 类型转换
                Object convertedValue = resolvedValue;
            	//是否可转换
                //	检查属性是否可写,必须有写方法(setter method)
                //	检查给定的属性路径是否指示索引或嵌套属性。比如user.name[0],这种就不行
                boolean convertible = bw.isWritableProperty(propertyName) &&
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                if (convertible) {
                    //转换器转换后的值
                    convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
                }
    
                //3. 缓存解析后的PropertyValue:resolvedValue -> convertedValue
                
                // Possibly store converted value in merged bean definition,
                // in order to avoid re-conversion for every created bean instance.
    
                //3.1 缓存情况1:解析后的对象实例没有被替换(地址匹配):如动态代理等,会直接替换对象。
                if (resolvedValue == originalValue) {
                    if (convertible) {
                        //可转换的,记录转换后的值
                        pv.setConvertedValue(convertedValue);
                    }
                    deepCopy.add(pv);
                }
                //3.2 缓存情况2:如果是可转换的,对象类型是TypedStringValue且不需要动态转换、转换后不是集合或数组
                //	originalValue如果是TypedStringValue,则类型转换器会将String转换成指定类型targetType
                else if (convertible && originalValue instanceof TypedStringValue &&
                        !((TypedStringValue) originalValue).isDynamic() &&
                        !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                    pv.setConvertedValue(convertedValue);
                    deepCopy.add(pv);
                }
                //3.3 不缓存:每次都重新解析
                else {
                    resolveNecessary = true;
                    //最终的值放到deepCopy
                    deepCopy.add(new PropertyValue(pv, convertedValue));
                }
            }
        }
    
        //所有的字段都能成功解析,不会再变,才会标记mpvs为转换完成,否则下次还需要动态解析
        //也可能是mpvs包含的部分字段需要解析
        if (mpvs != null && !resolveNecessary) {
            mpvs.setConverted();
        }
    
        // Set our (possibly massaged) deep copy.
        try {
            //BeanWrapper属性注入
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {...}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124

    BeanDefinitionValueResolver

    BeanDefinitionValueResolver#resolveValueIfNecessary(argName, value) 方法功能:解析 value 的真实类型,value 的类型不同,处理的结果也不同。本质就是进行依赖查找。

    • RuntimeBeanReference 类型:引用类型,根据 ref.beanType 或 ref.beanName 从容器中获取。
    • RuntimeBeanNameReference 类型:Spring EL 表达式解析 ref.beanName。
    • BeanDefinitionHolder 或 BeanDefinition 类型:根据 BeanDefinition 实例化 bean。
    • DependencyDescriptor:采用 beanFactory#resolveDependency 进行依赖查找。
    • ManagedList 等集合类型:规则和上述完全类似,只是返回集合而已。
    • 其它类型:如果是 String,则 Spring EL 表达式解析,其余的直接返回 originalValue。

    如 applyPropertyValues 中的 AutowiredPropertyMarker.INSTANCE 类型:表示使用 beanFactory#resolveDependency 进行依赖查找。BeanDefinitionBuilder 添加属性时就会使用时这些类型。
    在这里插入图片描述

    BeanWrapper属性注入

    BeanWrapper:对 Bean 操作的封装,如 JavaBean 的内省,属性的设置。其 bw.setPropertyValues(mpvs) 将属性注入到 bean 实例中。

    • BeanWrapperImpl:(默认)采用 PropertyDescriptor 进行注入,也就是 setter 方法反射注入,对应的处理器为 BeanPropertyHandler。
    • DirectFieldAccessor:采用字段注入,对应的处理器为 FieldPropertyHandler。

    核心代码:
    org.springframework.beans.BeanWrapperImpl.BeanPropertyHandler#setValue

    public void setValue(@Nullable Object value) throws Exception {
    	Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
    			((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
    			this.pd.getWriteMethod());
    	if (System.getSecurityManager() != null) {...}
    	else {
    		ReflectionUtils.makeAccessible(writeMethod);
    		writeMethod.invoke(getWrappedInstance(), value);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    反射set方法赋值。

  • 相关阅读:
    【Linux-Day10-信号量,共享内存,消息队列】
    写一个基于C语言的保守垃圾回收器
    synchronized 关键字背后的锁升级流程
    VSCode 最好的 Python 扩展,可大大提升你的生产力
    vue2学习之前端路由小案例(后台管理小案例)
    [Java反序列化]—Shiro反序列化(二)
    AndroidStudio smalidea插件下载
    SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.3 手机验证码案例 - 生成验证码
    计算机毕业设计之疫情防疫信息化管理系统
    0基础学three.js环境搭建(2)
  • 原文地址:https://blog.csdn.net/weixin_41947378/article/details/127336111