Spring注入 @Autowired & @Resource
- 1. 概述
- 1.1 职责
- 1.2 流程概述
- 2. Demo
- 3. AutowiredAnnotationBeanPostProcessor注册
- 4. 注册元数据
- 4.1 AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
- 4.2 AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata
- 4.3 AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
- 5. 字段注入逻辑
- 5.1 AutowiredAnnotationBeanPostProcessor#postProcessProperties
- 5.2 AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
- 5.3 解决依赖关系 DefaultListableBeanFactory#doResolveDependency
- 5.4 Autowired注入逻辑总结
- 6. @Resource注入方式
- 6.1 Demo
- 6.2 Resource注入逻辑
- 6.3 CommonAnnotationBeanPostProcessor#autowireResource
- 6.4 结论
1. 概述
1.1 职责
@Autowired注入是由AutowiredAnnotationBeanPostProcessor完成的。
@Resource注入是由CommonAnnotationBeanPostProcessor完成的。
由于两种方式代码重复率太高,原理基本一致,下面我们主要以AutowiredAnnotationBeanPostProcessor源码分析为主。
1.2 流程概述
AutowiredAnnotationBeanPostProcessor负责属性、方法的注入。
分为两个流程:
- 注册元数据:先将要注入的字段和方法组成元数据,放入缓存中。
- 赋值:通过缓存中的描述信息从beanFactory中获取bean,字段和方法注入。
2. Demo
AutoObjectA
@Component
public class AutoObjectA {
@Autowired
private AutoObjectB autoObjectB;
}
AutoObjectB
@Component
public class AutoObjectB {
}
3. AutowiredAnnotationBeanPostProcessor注册
在创建AnnotationConfigServletWebServerApplicationContext的时候,就已经注册了AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor。
SpringBoot 源码解析2:启动流程
AnnotationConfigUtils#registerAnnotationConfigProcessors
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
4. 注册元数据
SpringBoot 源码解析7:Bean的创建② AbstractAutowireCapableBeanFactory#createBean
在doCreateBean方法源码中,我们可以知道,在实例化bean之后,会通过applyMergedBeanDefinitionPostProcessors方法回调MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition。
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
AutowiredAnnotationBeanPostProcessor继承了MergedBeanDefinitionPostProcessor
元数据的注册的核心逻辑就在AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
4.1 AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
通过findAutowiringMetadata方法找到需要注入的元数据,然后还会检查一下成员变量。
暂时不知道checkConfigMembers的作用。
4.2 AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata
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.
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);
}
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
- 做了一个缓存injectionMetadataCache,将注入信息的流程与注入流程分开,注入时直接从缓存中获取信息。
- pvs为已经注入的属性,metadata.clear(pvs)会清除掉这些信息,不会重复注入。
4.3 AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
private String requiredParameterName = "required";
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
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.
}
}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
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<>();
// 1. 先扫描方法上面的注入注解
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> 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;
}
// 是否必须注入,默认为true,找不到bean就会抛出异常
boolean required = determineRequiredStatus(ann);
// 注册
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 2. 再扫描方法上面的注入注解
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 通过桥接方法找到原始的方法
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
// 判断方法上面是否有注入注解
MergedAnnotation<?> 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 AutowiredMethodElement(method, required, pd));
}
});
// 优先是否方法注入
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
这是获取需要注入的元数据的核心方法
- 支持的注入注解包含Autowired、Value、Inject。
- 不支持静态注入,因为静态属于类的信息。
- 将方法注入的元数据放入到前面,所以方法先注入,后面字段注入会覆盖方法注入。
- 字段注入创建的是AutowiredFieldElement, 方法注入创建的是AutowiredMethodElement。字段注入和方法注入的逻辑基本一样的,后面讲解以demo中的字段注入为例。
- 最终,将要注入的信息封装到InjectionMetadata,完成注入信息的注册。
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
return (elements.isEmpty() ? InjectionMetadata.EMPTY : new InjectionMetadata(clazz, elements));
}
5. 字段注入逻辑
AbstractAutowireCapableBeanFactory#populateBean方法负责对bean的属性的初始化。回调了InstantiationAwareBeanPostProcessor#postProcessProperties。
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
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;
}
}
}
每次调用postProcessProperties会传入PropertyValues
5.1 AutowiredAnnotationBeanPostProcessor#postProcessProperties
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
第二次调用findAutowiringMetadata从缓存中获取要注入的元素信息,并且将已经注入成功的pvs删除掉。
5.2 AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
// 将字段和是否强制注入封装城描述信息
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
// 获取类型转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 创建依赖的bean,也就是字段所对应的bean
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
// 创建bean依赖的bean失败
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
// 如果没有添加缓存,那么就会添加缓存
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
// 注册bean的依赖关系
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
// 设置属性的值
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
- 这是@Autowired注解字段注入的实现逻辑。将依赖的bean的描述信息封装在DependencyDescriptor 中,通过beanFactory.resolveDependency解决依赖,方法的返回值就是所依赖的bean。
- cached:缓存了bean的依赖信息。
- 最终通过反射,完成了字段的初始化。
总结:beanFactory.resolveDependency方法获取到依赖的bean,通过反射field.set(bean, value)对字段赋值。
5.3 解决依赖关系 DefaultListableBeanFactory#doResolveDependency
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
// 对@Value注解进行解析,返回的是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);
value = evaluateBeanDefinitionString(strVal, bd);
}
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()));
}
}
// 这里是对集合、数组、Map注入的支持
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 返回所有匹配的信息
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
// 如果根据type匹配多个,那么就解析@Primary或者Order匹配
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.
// By Type只能匹配到一个
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
// 这里By name取bean实例
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
// 校验bean是否与类型匹配
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);
}
}
- getAutowireCandidateResolver().getSuggestedValue():对@Value注解注入的支持。
- resolveMultipleBeans:对数组、集合、Map注入的支持。
- findAutowireCandidates:返回所有匹配的信息,返回一个map,key为beanName,如果依赖bean创建完毕,value就为依赖bean,否则就是beanClass。
为什么说@Autowired注解是By Type注入的呢?原因就在DefaultListableBeanFactory#findAutowireCandidates这个方法!
BeanFactoryUtils.beanNamesForTypeIncludingAncestors通过给定的类型,找到所有的对应的beanName,然后在通过beanName去获取Bean。
不要将@Autowired注入方式简简单单的理解为 通过类型直接匹配bean。在Spring中,不管是bean的注册(保存在beanDefinitionMap中,key为beanName)还是单例bean的保存(singletonObjects,key为beanName),他们的身份标识都为beanName,就算用户没有指定beanName,Spring中内置了BeanNameGenerator自动生成bean的名称。 - 如果有多个匹配的bean,那么就通过determineAutowireCandidate取最合适的那个,由@Primary注解和@Order决定。
- 上述说过,By Type匹配的时候,依赖bean还没有创建成功,返回的就是type,那么就会通过descriptor.resolveCandidate创建真正的bean。创建bean毫无疑问就要调用beanFactory.getBean。
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName);
}
- 这个方法的本身就是By Type注入。如果需要By Name 注入,就要调用AbstractAutowireCapableBeanFactory#resolveBeanByName。
5.4 Autowired注入逻辑总结
核心方法是doResolveDependency。首先是By Type取出所有的beanName,然后通过beanName从beanFactory取出bean,最后设置属性中。
6. @Resource注入方式
读了上述内容,我们知道了注入方法。那么,@Resource的注入方式是什么呢?
那么就要看CommonAnnotationBeanPostProcessor源码了。
6.1 Demo
@Component
public class ResourceA {
@Resource
private ResourceB resourceB;
}
@Component
public class ResourceB {
}
字段注册和Autowired逻辑基本一致
6.2 Resource注入逻辑
调用链:
- CommonAnnotationBeanPostProcessor#postProcessProperties
- InjectedElement#inject
- CommonAnnotationBeanPostProcessor.ResourceElement#getResourceToInject
- CommonAnnotationBeanPostProcessor#getResource
- CommonAnnotationBeanPostProcessor#autowireResource
6.3 CommonAnnotationBeanPostProcessor#autowireResource
protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
Object resource;
Set<String> autowiredBeanNames;
String name = element.name;
if (factory instanceof AutowireCapableBeanFactory) {
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
DependencyDescriptor descriptor = element.getDependencyDescriptor();
// 判断为True,就需要By Type的方式解决依赖
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 {
// 这里是By Name的方式解决依赖
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;
}
-
判断条件
条件一:fallbackToDefaultTypeMatch默认为true。
条件二:是否使用默认名称。如果用户指定了依赖的bean的名称,那么就认为指定的bean必然要存在,isDefaultName就为false,就需要By Name取获取依赖bean。否则就使用字段的名称。
条件三:beanName没有对应的实例或者beanDefinition。如果没有,那么就By Type去解决依赖关系。为什么这样呢?比如应该是
@Override
public boolean containsBean(String name) {
String beanName = transformedBeanName(name);
if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
}
// Not found -> check parent.
BeanFactory parentBeanFactory = getParentBeanFactory();
return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
}
- 只有满足同时上述三个条件才会By Type获取bean。所以也兼容 By Type注入。
- 为什么要有条件三呢?
因为ResourceB对应的bean被默认的BeanNamegenerator生成的beanName为"resourceB"。兼容了即使用户写错了变量名称,也要注入成功。比如:
@Resource
private ResourceB b;
6.4 结论
所以,@Resource注入逻辑如下:
- 如果用户指定了beanName,那么就通过beanName注入。
- 如果用户没有指定beanName,注入的字段名称存在对应的bean,那么就By Name注入。如果不存在对应的bean就是 By Type注入。