Spring原生依赖注入(已过时,不推荐使用)
AbstractAutowireCapableBeanFactory类内的 populateBean方法(属性注入)
resolvedAutowireMode就是
autowire值的编号
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// MutablePropertyValues是PropertyValues具体的实现类
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
ByType
ByName
AbstractAutowireCapableBeanFactory类的 autowireByName方法
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 当前Bean中能进行自动注入的属性名
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
// 遍历每个属性名,并去获取Bean对象,并设置到pvs中
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 记录一下propertyName对应的Bean被beanName给依赖了
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
获得注入的属性名字
属性描述器,这个pds里面存储的
就是 去分析 get和set方法 两个有其一就行 但是必须规范 set必须有形参,get必须有返回值,
getXXX/setXXX这个XXX就会被当作一个pd的name属性 pd里面会有readMethod或者writeMethod(根据实际分析而得的);
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
// BeanWrapper里面有实例对象
Set<String> result = new TreeSet<>();
PropertyValues pvs = mbd.getPropertyValues();
// 属性描述器(规范)
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
// 什么样的属性能进行自动注入?
// 1.该属性有对应的set方法
// 2.没有在ignoredDependencyTypes中
// 3.如果该属性对应的set方法是实现的某个接口中所定义的,那么接口没有在ignoredDependencyInterfaces中
// 4.属性类型不是简单类型,比如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);
}
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);这个结果,就是bds通过遍历,并且过滤(必须有一个set方法)得到的一个集合
过滤条件: 必须有set方法,这个属性不是简单类型(String int ......)
之前操作BD时没有手动指定属性值
// 遍历每个属性名,并去获取Bean对象,并设置到pvs中
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
containsBean(propertyName)
需要 这个属性 有BD在BD集合中,并且是单例的 ,最后放到pvs中
Spring的扩展依赖注入(@Autowired 或者 @Resource...推荐)
@Autowired @Value @Inject
找到对应的切点
applyMergedBeanDefinitionPostProcessors中
会遍历循环 MergedBeanDefinitionPostProcessor
会找到一个 AutowiredAnnotationBeanPostProcessor 的一个后置处理器
这个方法这里执行后,会将找到的切点放到injectionMetadataCache这个缓存中,下次调用这个就可以直接拿到 类的对应切点
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所有注入点存放发地方
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);
}
// 解析注入点并缓存 就是哪一个字段 / 方法上加了 @AutoWare 就是一个注入点
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
buildAutowiringMetadata方法
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
// 如果一个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 -> {
// 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;
}
// 构造注入点
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);
}
大概流程:
首先会判断这个类是不是需要进行Autowired切点的类
主要就是判断这个类是不是 java包下的,不是才会继续找切点
循环找切点(先找子类,再找父类,直到object)
找 字段切点
遍历所有字段
找哪些字段上标有@Autowired @Value @Inject
判断这个字段是不是静态的,如果是,直接忽略这个字段
{原因:假设这个场景:A类是原型的 B类也是原型的
A 类中 有B类的成员遍历 加了@Autowired 还是静态的
那当我调用了两次getBean(A),就会得到两个 A对象,但是当我们获 得第二个对象时,就会把第一个对象的B成员属性给更改了,所以Spring认为这个是不符合规范的,所以 就忽略了静态字段
}
会获取 @Autowired 的required的值(是否必须要依赖注入,如果是false,就算没找到要注入的值,直接给一个null,如果是ture 没有找到,就会报错)
如果符合以上要求 ,就将这个 切入点以及required(封装为AutowiredFieldElement)记录下来
一个类的 切点字段 会放到currElements
{有个细节,因为在一个循环里,如果这个类有父类,在遍历父类之后,会将父类的currElements放到elements(类及其父类的currElements集合)的最前面,也是符合逻辑的,要注入属性,父类优先}
找 方法切点
会有一个(桥接方法),大概意思就是,方法参数出现了泛型,字节码层面会有两个方法,一个是方法参数是Object 另一个就是真正要注入的,会根据一系列判断,找到那个真正要注入的(可以忽略,因为我也不知道是不是正确的,但是有这个逻辑)
遍历一个类的所有method上是否存在@Autowired、@Value、@Inject中的其中一个
排除static(理由和字段的差不多)
这个方法最好有 至少有一个形参 (要不然 注入个 der)(没有就会打印一个日志,但并不会排除),
获取required的值
如果符合以上要求 ,就将这个 切入点以及required(封装为AutowiredMethodElement)记录下来
一个类的 切点方法 也 会放到currElements
统一封装到InjectionMetadata这个类里面
开始属性注入
会找到AutowiredAnnotationBeanPostProcessor 的postProcessProperties方法
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 找注入点(所有被@Autowired注解了的Field或Method)
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这个方法以经在上面执行过了,这次直接从缓存中拿就行,不需要再次遍历字段和方法了
拿到注入点后,就要开始对注入点进行属性注入了
会遍历所有的注入点(AutowiredMethodElement,AutowiredFieldElement)会调用这两个对应 的inject方法
AutowiredFieldElement
@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);
}
}
第一次获取没有缓存:
会直接调用这个方法 获得这个要注入的值
// 根据filed从BeanFactory中查到的匹配的Bean对象
value = resolveFieldValue(field, bean, beanName);
通过反射直接写到对象中
// 反射给filed赋值
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
AutowiredMethodElement
@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();
}
}
}
和字段的差不多,只是 把单个字段 换成了 ,方法参数值的数组,最后,
通过反射 ,调用这个方法
怎么从ioc找
resolveFieldValue(字段)
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
//字段 / 方法参数 的名字 和 类型
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();
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;
}
}
DependencyDescriptor 是 依赖(字段)的描述器,里面有 ,字段name 和 字段type,
还有bean的class
DependencyDescriptor在找方法参数那里是一个数组
重要的语句
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
这个resolveDependency中一般都是执行这段代码
// 在属性或set方法上使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选Bean
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// descriptor表示某个属性或某个set方法
// requestingBeanName表示正在进行依赖注入的Bean
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
解析@Lazy注解
如果字段或者方法参数上标有@Lazy注解,就会在这里根据类型构建一个代理对象,当我们真正去调用这个字段的方法,才会去容器里找对应的bean,然后调用bean的方法,(懒o_o)
没有标
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> 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<String, Object> 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<String, Object> 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);
}
}
解析@Value
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()));
}
}
先获得字段/方法参数 的 类型值
读取@Value(“值”)的 值
字符串的解读:
${}代表 去找环境变量(java -d 后面的 ; 计算机配的环境变量 ;自己手动配的)
#{} 这样的代表spring表达式
这个非常不常用
举个例子#{orderService} 就是去容器里找一个叫orderService的对象赋给字段/方法参数
“2313123”直接就是字符串 或者上面是¥{1231} ,#{12313}原因就是环境变量里没找到,或者容器里没找到 ,就认为可能就是要赋值这个字符串
这里的逻辑,就是 通过类型转换器 来实现的,看看有没有能转成功的
没有就会抛异常
没有标@Value
类型判断(是不是返回多个值) 只举一个Map 其他原理差不多,关键,我们也不会这么用0_0
如果是集合/Map/数组
// 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
Map
判断map的key是不是String 不是直接返回null (指的是multipleBeans 是null,不是找的方法(doResolveDependency)结束了)
findAutowireCandidates找到所有符合类型的bean,key是beanname,value就是bean对象,
能找到就返回,没找到就返回null,继续下面的逻辑
else if (Map.class == type) {
ResolvableType mapType = descriptor.getResolvableType().asMap();
Class<?> keyType = mapType.resolveGeneric(0);
// 如果Map的key不是String
if (String.class != keyType) {
return null;
}
Class<?> valueType = mapType.resolveGeneric(1);
if (valueType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}
根据类型判断只要一个的
// 找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClass
Map<String, Object> 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<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
// candidates表示根据类型所找到的多个Bean,判断这些Bean中是否有一个是@Primary的
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// 取优先级最高的Bean
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
// 匹配descriptor的名字,要么是字段的名字,要么是set方法入参的名字
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
// resolvableDependencies记录了某个类型对应某个Bean,启动Spring时会进行设置,比如BeanFactory.class对应BeanFactory实例
// 注意:如果是Spring自己的byType,descriptor.getDependencyName()将返回空,只有是@Autowired才会方法属性名或方法参数名
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
- 首先会找到,所有符合类型的bean,并将beaname和bean封装成一个Map
- 如果map里元素数量只有一个,会直接确定autowiredBeanName instanceCandidate
- 如果有多个就会进行过滤(@Primary/Priority/ByName)
- 这三个从上到下,有一个能找到就算成功
- @Primary
- 这个注解的解析在扫描BD的时候就已经解析了,结果是放到了,BD里面
- determinePrimaryCandidate的逻辑就是,对根据类型找到的结果循环遍历,找到各自的BD,如果发现有一个标注了Primary,最后就会返回这个bean的beanname,如果发现有多个都标注了,直接抛异常
- @Priority(不能标注到方法上)
- 这个就是相当于将根据类型找到的结果进行了排序,根据Priority指定的数字,数字越小,级别越高,最后选出级别最高的那个,最后就会返回这个bean的beanname
- ByName
- 循环遍历,对根据类型找到的结果 和 依赖(字段)的描述器里的name进行匹配,找不到就返回空,找的到就返回beanname
- 这个determineAutowireCandidate的结果如果是空的,就会判断required的值,如果为true,直接抛异常,是false,就返回空(最后注入点注入的就是空)
findAutowireCandidates根据类型获得Map集合
- 主要 就是 找beanname(因为 如果是原型bean 就不会在单例池里面,所以这个是去BD里面找的)
-
从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化
- String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.isEager());
-
// 从本容器中找
String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit); -
这个方法里面,还会去父容器里面找,最后合并(合并的list集合,就算父子容器里面这个类型的beanname 没有重复的)
-
-
getBeanNamesForType (DefaultListableBeanFactory)怎么找
-
会有缓存判断 最后掉下面这个方法
-
doGetBeanNamesForTyp(大概意思 -- 就是根据BD 的参数进行类型匹配,然后将这个符合这个类型的 所有 的 beanName 放到一个 字符串的集合中)
-
-
-
找到beanName后 会生成一个result的Map<String, Object>集合
-
首先会在下面这个集合中 根据类型获得一些bean 但是 从这里取出来的 放到 result集合的key是由Spring生成的(有一定规则,但是不是beanname)
-
下来就会开始筛选了
-
会遍历 上面得到的beanname集合,会判断是不是自己注入自己(这个不太合适)
-
isAutowireCandidate 会有三层筛选(责任链模式)
-
SimpleAutowireCandidateResolver 会判断 @Bean(autowireCandidate = true)这个是不是true
-
GenericTypeAwareAutowireCandidateResolver 会进行 泛型判断(这个超级复杂)
-
QualifierAnnotationAutowireCandidateResolver 会对 @Qualifier 的value的值进行判断
-
三层 过后 会将这个beanname 和 bean 放到 result中
-
-
如何经历了这么多 result还是空,这时候才会考虑(自己注入自己)
-
如果有 会将这个beanname 和 bean 放到 result中
-
-
如果也找不到自己注入自己 那就是真的没了
继续过滤 还有三层
如果 findAutowireCandidates 返回的结果中 map 的数据是多个 ,
先判断 @primary 如果有 直接找到返回
再排序 @Priority(1) 通过这个注解 来排序,如果都没标,就会进入到最后一层,如果标了,就是数字越小,优先级越高 ,最高的直接返回
最后一道防线 通过 map的key,也就是byname,将字段名作为key,也就是匹配beanname找到那个对象,找到了就返回,没找到就抛异常
resolveMethodArguments(方法)
@Resource
CommonAnnotationBeanPostProcessor这个类实现的
大体思路(和具体实现的还存在一定的差别)
就是 先找注入点 然后遍历注入点(反射写到bean里面)
这个 是先判断 name
如果 BD里面存在这个 name 就直接调用getBean方法
如果不存在 就 再调用 bytype(这个和上面的差不多)
注意 Resource 是java提供的 ,spring只是支持这个注解
Autowired是spring 提供的
Resource 可能别的框架也支持,换框架时可以减少对代码的修改
性能上 没有什么区别;