spring-framework-5.3.10 版本
依赖注入代码的入口在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 。如果想搞清楚为什么是这里需要去学习下Bean的生命周期,这里就不介绍了。
@Autowired
private OrderService orderService;
使用@Autowired注解,在程序执行时会调用populateBean方法中的postProcessProperties
最终会进入到org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties。首先会去查找注入点,注入点也就是需要进行自动注入的属性和方法。
findAutowiringMetadata 中会调用 buildAutowiringMetadata 这个就是寻找注入点最后核心的方法。
先来看一下全貌,然后我们一起逐行进行分析。这段代码可以分成两大块14-30行用来寻找属性的注入点,33到60行用来寻找方法的注入点。
private InjectionMetadata buildAutowiringMetadata(final Class> clazz) {
// 如果一个Bean的类型是String...,那么则根本不需要进行依赖注入
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List elements = new ArrayList<>();
Class> targetClass = clazz;
do {
final List currElements = new ArrayList<>();
// 遍历targetClass中的所有Field
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// field上是否存在@Autowired、@Value、@Inject中的其中一个
MergedAnnotation> ann = findAutowiredAnnotation(field);
if (ann != null) {
// static filed不是注入点,不会进行自动注入
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
//获取@Autowired中的required属性的值
boolean required = determineRequiredStatus(ann);
// 构造注入点
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 遍历targetClass中的所有Method
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
// method上是否存在@Autowired、@Value、@Inject中的其中一个
MergedAnnotation> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
// static method不是注入点,不会进行自动注入
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
// set方法最好有入参
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 AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
3-5行 判断当前类是否不需要寻找注入点。底层判断逻辑代码如下
static boolean hasPlainJavaAnnotationsOnly(Class> type) {
return (type.getName().startsWith("java.") || type == Ordered.class);
}
14-30行用来寻找属性的注入点
14行 ReflectionUtils.doWithLocalFields 会遍历当前类里面的所有字段。
16行 然后去findAutowiredAnnotation 判断当前字段上是否存在@Autowired、@Value、@Inject中的其中一个,如果存在任意一个则当前字段判断为注入点。
19行 如果属性是static的不进行注入,因为在原型模式下,static属性多个对象赋值时会存在覆盖。
26行 查看当前属性是否要求必须注入,required默认为true。
28行 将找到的注入点放入currElements,最终通过67行 InjectionMetadata.forElements 封装成InjectionMetadata对象。
33到60行用来寻找方法的注入点。寻找方法注入点和属性注入点类似。主要说明以下几个地方
35-38行 这里判断是否为桥接方法,并对桥接方法进行过滤。 这里主要是处理泛型接口的实现类中的注入,了解即可。
50行 这里即使方法上没有入参,如果添加了@Autowired注解方法也会执行。
注意第10-65行,是一个do while,看第63行可以理解,逻辑时先找自己的注入点,然后去找父类。知道找到所有注入点。
67行 InjectionMetadata.forElements 将属性和方法上的注入点,封装成InjectionMetadata对象,并返回
寻找到注入点以后,接下来就是对注入点的属性和方法进行依赖注入了。metadata.inject(bean, beanName, pvs); 实现依赖注入
同样的注入也分为属性注入和方法注入
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
// 对于原型Bean,第一次创建的时候,也找注入点,然后进行注入,此时cached为false,注入完了之后cached为true
// 第二次创建的时候,先找注入点(此时会拿到缓存好的注入点),也就是AutowiredFieldElement对象,此时cache为true,也就进到此处了
// 注入点内并没有缓存被注入的具体Bean对象,而是beanName,这样就能保证注入到不同的原型Bean对象
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
// 根据filed从BeanFactory中查到的匹配的Bean对象
value = resolveFieldValue(field, bean, beanName);
}
// 反射给filed赋值
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
6-17行 先判断缓存里是否有,如果没有调用resolveFieldValue获取到属性值
24-26行 利用反射将属性值注入到属性
resolveFieldValue方法是注入的核心,我们进到这个方法里看看
@Nullable
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
Object value;
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
// 注册一下beanName依赖了autowiredBeanNames,
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
// 构造一个ShortcutDependencyDescriptor作为缓存,保存了当前filed所匹配的autowiredBeanName,而不是对应的bean对象(考虑原型bean)
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
return value;
}
4行 生成依赖描述器
12行 是一个核心方法resolveDependency。我们在进入这个方法来看看
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// 用来获取方法入参名字的
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 所需要的类型是Optional
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
// 所需要的的类型是ObjectFactory,或ObjectProvider
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
// 在属性或set方法上使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选Bean
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// descriptor表示某个属性或某个set方法
// requestingBeanName表示正在进行依赖注入的Bean
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
6行 获取方法的入参名字
8-19行 处理一些特殊的情况。不做分析
22-28行 这里才是我们常用的情况
22行 判断属性上是否添加了@Lazy注解,或者方法参数前面是否添加了@Lazy注解。如果添加了@Lazy注解,说明属性不会在这里进行注入。而是等待真正使用的时候才进行注入,此时属性并没有真正注入,而是返回一个代理对象。在真正使用时通过代理对象进行依赖注入,并返回注入后的对象。
如果没有添加@Lazy注解,会进入到28行 doResolveDependency 这是依赖注入的重中之重。
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 如果当前descriptor之前做过依赖注入了,则可以直接取shortcut了,相当于缓存
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class> type = descriptor.getDependencyType();
// 获取@Value所指定的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
// 占位符填充(${})
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
// 解析Spring表达式(#{})
value = evaluateBeanDefinitionString(strVal, bd);
}
// 将value转化为descriptor所对应的类型
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
// 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass
Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// required为true,抛异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
// 根据类型找到了多个Bean,进一步筛选出某一个, @Primary-->优先级最高--->name
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
// 记录匹配过的beanName
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBean
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
// 处理只有名字没有对象的特殊情况
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
15-36行 是对@Value注解的解析
19行 占位符填充(${}) 从properties文件中或者运行时使用-D指定的环境变量中。以占位符作为key,读取值填充到属性中。
@Value("${user.name}")
private String name;
使用properties时需要引入
@PropertySource("classpath:spring.properties")
public class AppConfig {
23行 解析Spring表达式(#{}) 从spring容器中找到符合的bean
@Value("#{orderServie}")
private OrderService orderService;
25-35行 是一个类型转化器,可以对@Value解析出来的值利用转化器转成目标属性的类型
38-42行 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了。例如
@Autowired
private Map orderServiceMap;
45行findAutowireCandidates根据传入的类型和beanName找到所需的Bean,Map
// 找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass
Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
46-51行 如果没有找到bean,并且isRequired为true则抛异常,如果isRequired为false则返回null
if (matchingBeans.isEmpty()) {
// required为true,抛异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
57-72行 如果找到了多个Bean,需要调用determineAutowireCandidate方法进行过滤,找到符合条件的唯一Bean
determineAutowireCandidate中会根据 @Primary-->@Priority优先级最高--->name 的顺序取Bean。 @Priority只能写在类上。
如果获取不到判断是否isRequired为ture,逻辑和上面一样。
if (matchingBeans.size() > 1) {
// 根据类型找到了多个Bean,进一步筛选出某一个, @Primary-->优先级最高--->name
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
73-78行 如果只找到了唯一的bean,那么这个bean就是我们想要的了。
else {
// We have exactly one match.
Map.Entry entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
85-87行 后面的逻辑就是将筛选出来的bean对应的class进行实例化,然后将实例化以后的bean返回给属性进行注入
// 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBean
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
90-95行 处理只有名字,bean为null的特殊情况。
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
我们在回头看下45行findAutowireCandidates
protected Map findAutowireCandidates(
@Nullable String beanName, Class> requiredType, DependencyDescriptor descriptor) {
// 从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map result = CollectionUtils.newLinkedHashMap(candidateNames.length);
// 根据类型从resolvableDependencies中匹配Bean,resolvableDependencies中存放的是类型:Bean对象,比如BeanFactory.class:BeanFactory对象,在Spring启动时设置
for (Map.Entry, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
for (String candidate : candidateNames) {
// 如果不是自己,则判断该candidate到底能不能用来进行自动注入
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 为空要么是真的没有匹配的,要么是匹配的自己
if (result.isEmpty()) {
// 需要匹配的类型是不是Map、数组之类的
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 匹配的是自己,被自己添加到result中
if (result.isEmpty() && !multiple) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
5行 从spring容器中,通过单例池和BeanDefinitionMap中找到符合的Bean
10-21行 遍历 , Object> resolvableDependencies 中记录了一个Class对应的Bean对象是什么
24-28行 candidateNames中存储了符合条件的bean的名字。 如果是自己注入自己,例如下面这种,如果还存在另外一个UserService类型,优先使用非自己的bean进行注入。
public class UserService {
@Autowired
UserService userService;
isAutowireCandidate用来判断一个bean是否可以进行依赖注入。这里用到了责任链
org.springframework.beans.factory.support.SimpleAutowireCandidateResolver#isAutowireCandidate
org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver#isAutowireCandidate 处理泛型
org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate 处理Qualifier
@Bean(autowireCandidate = false)
public UserService userService() {
return new UserService();
}
32-56行 判断是否存在符合条件的bean,如果没有找到符合条件的bean.在看看自己是否是符合条件的。因为在24-28行中排出了自己。
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 如果pvs中已经有当前注入点的值了,则跳过注入
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
try {
arguments = resolveCachedArguments(beanName);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
arguments = resolveMethodArguments(method, bean, beanName);
}
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
方法注入和属性注入类似,只是方法的入参可能是多个,所以会遍历每一个参数去获取参数值,然后注入。
resolveMethodArguments方法中同样会调用resolveDependency。这里的逻辑就和上面一样了。
找出对象中所有的set方法,然后将setXXX后面的XXX作为属性名称,在容器中取得Bean进行注入。
@ComponentScan("com.mtb")
public class AppConfig {
@Bean(autowire = Autowire.BY_NAME)
public UserService userService() {
return new UserService();
}
}
@Component
public class UserService {
private OrderService orderService;
public void test() {
System.out.println(orderService);
}
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
}
使用这种方式会进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireByName
进入autowireByName后,会通过unsatisfiedNonSimpleProperties拿到bean中需要注入的所有属性名字
进入以后,先获取属性描述器
PropertyDescriptor中有几个属性:
name:这个name并不是方法的名字,而是拿方法名字进过处理后的名字
如果方法名字以“get”开头,比如“getXXX”,那么name=XXX
如果方法名字以“is”开头,比如“isXXX”,那么name=XXX
如果方法名字以“set”开头,比如“setXXX”,那么name=XXX
readMethodRef:表示get方法的Method对象的引用
readMethodName:表示get方法的名字
writeMethodRef:表示set方法的Method对象的引用
writeMethodName:表示set方法的名字
propertyTypeRef:如果有get方法那么对应的就是返回值的类型,如果是set方法那么对应的就是set方法中唯一参数的类型
这里需要注意getPropertyDescriptors获取的不是对象中的属性,而是对象中的set方法,然后将set方法后面内容作为属性名。例如userService中的setOrderService,会把set后面的orderSercie作为属性名字。所以使用byName时,必须要有对应的set方法。
通过debug我们可以看到pds中解析出来了orderService属性
pvs.contains(pd.getName()) 如果在依赖注入前,已经注入了值(例如程序员使用了beanDefinition设置了值),那么不在自动注入。
BeanUtils.isSimpleProperty(pd.getPropertyType()) 如果是简单类型也不注入
简单类型如下:
public static boolean isSimpleValueType(Class> type) {
return (Void.class != type && void.class != type &&
(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));
}
执行完unsatisfiedNonSimpleProperties方法后,获取到了所有需要注入的属性。然后通过getBean获取bean,加入到pvs中。
最终会在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 方法中调用applyPropertyValues 完成注入
Autowire.BY_TYPE的流程与BY_NAME相似。 byType或通过入参去查找对象。
@resource注解通过org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#findResourceMetadata查找注入点 ,调用buildResourceMetadata查找添加了@Resouce注解的属性或方法。 如果属性是static的会报错。
流程和@Autowired类似,核心调用方法如下
org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement#inject
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.ResourceElement#getResourceToInject
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.ResourceElement#ResourceElement
public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
super(member, pd);
Resource resource = ae.getAnnotation(Resource.class);
String resourceName = resource.name();
Class> resourceType = resource.type();
// 使用@Resource时没有指定具体的name,那么则用field的name,或setXxx()中的xxx
this.isDefaultName = !StringUtils.hasLength(resourceName);
if (this.isDefaultName) {
resourceName = this.member.getName();
if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
resourceName = Introspector.decapitalize(resourceName.substring(3));
}
}
// 使用@Resource时指定了具体的name,进行占位符填充
else if (embeddedValueResolver != null) {
resourceName = embeddedValueResolver.resolveStringValue(resourceName);
}
// @Resource除开可以指定bean,还可以指定type,type默认为Object
if (Object.class != resourceType) {
// 如果指定了type,则验证一下和field的类型或set方法的第一个参数类型,是否和所指定的resourceType匹配
checkResourceType(resourceType);
}
else {
// No resource type specified... check field/method.
resourceType = getResourceType();
}
this.name = (resourceName != null ? resourceName : "");
this.lookupType = resourceType;
String lookupValue = resource.lookup();
this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
Lazy lazy = ae.getAnnotation(Lazy.class);
this.lazyLookup = (lazy != null && lazy.value());
}
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#autowireResource
protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
Object resource;
Set autowiredBeanNames;
String name = element.name;
if (factory instanceof AutowireCapableBeanFactory) {
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
DependencyDescriptor descriptor = element.getDependencyDescriptor();
// 假设@Resource中没有指定name,并且field的name或setXxx()的xxx不存在对应的bean,那么则根据field类型或方法参数类型从BeanFactory去找
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
autowiredBeanNames = new LinkedHashSet<>();
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
}
}
else {
resource = beanFactory.resolveBeanByName(name, descriptor);
autowiredBeanNames = Collections.singleton(name);
}
}
else {
resource = factory.getBean(name, element.lookupType);
autowiredBeanNames = Collections.singleton(name);
}
if (factory instanceof ConfigurableBeanFactory) {
ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
for (String autowiredBeanName : autowiredBeanNames) {
if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
}
}
}
return resource;
}
@Resource 先byName再byType , @Autowired 先byType 再byName
@Resource 是jdk的注解,@Autowired 是spring的注解