我们会经常使用Autowired、Resource、Value这些注解给属性赋值。 那么这几个注解是怎么给属性赋值的呢?还有其他的方法可以给属性赋值吗?使用Bean注解set方法,设置依赖注入方式(byName,byType)。 配置类 bean 测试 上面几张图:在配置类中使用Bean注解并设置注入方式,配置bean。 这种方式在spring中已经被定义为过期的方法,但是还能用,只是spring不建议使用。 person类的属性上并没有加Autowired,但是也能注入成功。 上图这段代码就是记录这种注入方式的代码,记住是记录,意思是说:只要用这种方式注入bean的spring都会在这个地方记录,就是将这些bean的名字存到一个集合中,方便后续注入。 PropertyDescriptor〔〕pdsbw。getPropertyDescriptors(); PropertyDescriptor:属性描述器,是javaBean里自带的。在这个属性描述器里会记录属性的名字,属性的set方法,get方法,等等。 前提是必须要有set方法或是get方法,如果一个类里只定义了属性,没有set方法或则是getf方法,那么也是拿不到这个属性的。 PropertyDescriptor中的name属性是通过解析set方法获取的。例如:setOr123,那么name属性的值就是or123。 spring在拿到所有属性后进行循环遍历for(PropertyDescriptorpd:pds){if(pd。getWriteMethod()!null!isExcludedFromDependencyCheck(pd)!pvs。contains(pd。getName())!BeanUtils。isSimpleProperty(pd。getPropertyType())){result。add(pd。getName());}}pd。getWriteMethod()!null:将没有set方法的属性给过滤掉。!pvs。contains(pd。getName()):将在MergedBeanDefinitionPostProcessor。postProcessMergedBeanDefinition方法中赋值过的属性过滤掉。!BeanUtils。isSimpleProperty(pd。getPropertyType()):将简单类型的属性过滤掉。 上图这个方法的最后面,就是下面这段代码if(pvs!null){applyPropertyValues(beanName,mbd,bw,pvs);} 将记录属性进行赋值。Autowired,Value,Resource给属性赋值 上图中的1是处理Autowired,Value,2是处理Resource。 以下主要看是AutowiredAnnotationBeanPostProcessor这个实现类。 上图中可以看到AutowiredAnnotationBeanPostProcessor实现了SmartInstantiationAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor这两个接口。 MergedBeanDefinitionPostProcessor。postProcessMergedBeanDefinition寻找注入点 根据类找到注入点 注入点:加了Autowired的属性或者方法。 ReflectionUtils。doWithLocalFields(targetClass,field{MergedA?annfindAutowiredAnnotation(field);if(ann!null){if(Modifier。isStatic(field。getModifiers())){if(logger。isInfoEnabled()){logger。info(Autowiredannotationisnotsupportedonstaticfields:field);}}booleanrequireddetermineRequiredStatus(ann);currElements。add(newAutowiredFieldElement(field,required));}}); 上述代码就是拿到类的所有属性,然后循环判断属性上面有没有加注解(Autowired或Value只要有一个注解就行)如果有注解且不是静态属性,就会加入到缓存中currElements。 1。静态的属性属于类的,不依赖于某个对象,也可以称为类属性。不同的对象都可以访问到类的属性。带参数的构造方法中不能包含静态的属性。它的生命随着类的消亡而消亡。 2。非静态属性只能属于某个对象,其它的对象不能访问它的属性。随着对象的消亡而消亡。 booleanrequireddetermineRequiredStatus(ann); 这行代码的作用就是处理required的,如果等于true就是必须要给该属性赋值,如果没有值就会报异常。ReflectionUtils。doWithLocalMethods(targetClass,method{MethodbridgedMethodBridgeMethodResolver。findBridgedMethod(method);if(!BridgeMethodResolver。isVisibilityBridgeMethodPair(method,bridgedMethod)){}MergedA?annfindAutowiredAnnotation(bridgedMethod);if(ann!nullmethod。equals(ClassUtils。getMostSpecificMethod(method,clazz))){if(Modifier。isStatic(method。getModifiers())){if(logger。isInfoEnabled()){logger。info(Autowiredannotationisnotsupportedonstaticmethods:method);}}if(method。getParameterCount()0){if(logger。isInfoEnabled()){logger。info(Autowiredannotationshouldonlybeusedonmethodswithparameters:method);}}booleanrequireddetermineRequiredStatus(ann);PropertyDescriptorpdBeanUtils。findPropertyForMethod(bridgedMethod,clazz);currElements。add(newAutowiredMethodElement(method,required,pd));}}); 上述这段代码是处理方法的,和上面的属性大致差不多。 唯一不同的是:MethodbridgedMethodBridgeMethodResolver。findBridgedMethod(method);if(!BridgeMethodResolver。isVisibilityBridgeMethodPair(method,bridgedMethod)){} 这个就是处理桥接方法,有兴趣的可以搜一下。 if(!AnnotationUtils。isCandidateClass(clazz,this。autowiredAnnotationTypes)){returnInjectionMetadata。EMPTY;} 这段代码就是判断这个bean的类型。如果是String等基础数据类型则不需要寻找注入点,就会直接返回。 SmartInstantiationAwareBeanPostProcessor。postProcessProperties主要是处理属性 在拿到注入点后就会执行这个方法,这个方法中会找到注入点的值,并给注入点赋值。 标号1的地方是找值,找到值后,就会执行标号2,给注入点赋值。