本文重点:
- Spring 如何挑选合适的方法创建bean
- 为什么使用构造注入 注入自己会失败
- @Autowired 与 @Resource的区别 、原理
准备工作
准备三个接口 及对应的实现类
public interface IAddress { String getAddress(); }
@Component
@Data
public class AddressA implements IAddress{
public String getAddress() { return "AddressA"; }
}
@Component
@Primary
@Data
public class AddressB implements IAddress{
public String getAddress() { return "AddressB"; }
}
---------------------
public interface IName { String getName(); }
@Component
@Data
public class NameA implements IName {
public String getName() { return "NameA"; }
}
@Component
public class NameB implements IName {
public String getName() return "NameB"; }
}
----------------------
public interface ISex { String getSex(); }
@Component
@Data
public class SexA implements ISex{
public String getSex() { return "SexA"; }
}
@Component
@Primary
@Data
public class SexB implements ISex{
public String getSex() { return "SexB"; }
}
AddressB ,SexB有 @Primary注解
1.有参构造
现在我们测试一种场景,只有一个构造方法
public TestA(List<IName> names, IAddress iAddress, IName nameA, @Qualifier("sexA") ISex iSex) {
this.names = names;
this.iAddress = iAddress;
this.iName = nameA;
this.iSex = iSex;
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("structure:{}",this);
}
structure: TestA(names=[NameA(), NameB()], iAddress=AddressB(), iName=NameA(), iSex=SexA())
这里唯一有歧义的地方是iName的candidate了,先说结论:有@Qualifier的优先,其次@Primary,再之后根据名称查找,最后找不到就抛异常了,下面我们看下依赖是如何注入的
有了上一篇 Spring ioc处理机制 juejin.cn/post/707235… 的基础,我们直接找到创建bean的位置 ,AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
...
if (mbd.getFactoryMethodName() != null) {
@Bean处理位置
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
...调用 SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors 筛选出合适的构造器,这里是AutowiredAnnotationBeanPostProcessor 在处理
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
...反射获取无参给构造 创建对象 到这一步如果没有无参构造就会抛异常了...
return instantiateBean(beanName, mbd);
}
我们先看下如何决定构造器的
1.1AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
...检查带@LookUp注解的方法...
//从缓存中获取 这个类被解析过一遍就不会再解析了
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
synchronized (this.candidateConstructorsCache) {
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor<?>[] rawCandidates;
try {
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
...
}
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
//遍历构造器数组 上次发现的带@Autowired @Inject的构造器放在这里 做唯一性判断
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
for (Constructor<?> candidate : rawCandidates) {
...查找@Autowired @Inject 注解...
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
if (ann != null) {
//多个带@Autowired @Inject 的构造器就抛异常了
}
candidates.add(candidate);
}
else if (candidate.getParameterCount() == 0) {
//无参构造
defaultConstructor = candidate;
}
}
if (!candidates.isEmpty()) {
if (requiredConstructor == null) {
//之所以会进这个if 是因为声明了@Autowired(required=false)
if (defaultConstructor != null) {
//添加无参构造
candidates.add(defaultConstructor);
}
}
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
//只有一个有参构造 那就选它了
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
....
else {
candidateConstructors = new Constructor<?>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
//综上 这里能返回基本上 只有一个有参构造 、多个构造包含一个带@Autowired/@Inject注解的构造、多个带@Autowired(required=false)的构造
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
1.2 ConstructorResolver#autowireConstructor
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
...
if (constructorToUse == null || argsToUse == null) {
Constructor<?>[] candidates = chosenCtors;
...
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
//只有一个构造 且无参 直接反射调就好
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
//剩下的就是筛选构造 和获取参数了
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
...多个构造candidate 调用过程中报错 是会继续执行下一个构造的...
for (Constructor<?> candidate : candidates) {
int parameterCount = candidate.getParameterCount();
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
//看源码注释也知道 多个构造方法 在上面根据参数个数排序 优先调用参数多的构造方法
break;
}
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
//一般resolvedValues就是个空对象
if (resolvedValues != null) {
try {
...获取参数名 String[] paramNames ...
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
...
}
}
else {
...
}
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
if (typeDiffWeight < minTypeDiffWeight) {
//进入到这里 基本相当于break了 已经决定好了构造 和对应的参数了 除非后续有参数个数一致的构造,那就取后面那个
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
...
}
....
}
//反射构造 创建bean
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
1.3 ConstructorResolver#createArgumentArray
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
.....
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
Class<?> paramType = paramTypes[paramIndex];
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
....
else {
//一般直接进入这里 记住这个类:MethodParameter ,Spring mvc handler目标方法 invoke前也是基于MethodParameter解析参数的
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
....
try {
//内部调用到doResolveDependency (ObjectProvider,ObjectFactory会在调用对应方法时是才进行查找注入,这里相当于是注入了函数)
Object autowiredArgument = resolveAutowiredArgument(
methodParam, beanName, autowiredBeanNames, converter, fallback);
...
}
catch (BeansException ex) {
...
}
}
}
...
return args;
}
1.4 DefaultListableBeanFactory#doResolveDependency
这个方法是个通用方法 大部分的依赖处理都会走到这 @Value @Autowired..
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
...
//提取出@Value 中的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
//基于 PropertySourcesPropertyResolver 解析 ${}占位符 返回 解析出来的值或默认值 OriginTrackedMapPropertySource解析yml中配置的变量
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
//如果是类似 #{${}} spel表达式 还会进一步解析
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
//基于Converter进行类型转换 比如String -> Enum,Date (Date没有默认的converter,是基于Object->Object,用的是构造方法,需要的话可以自己实现,mvc的的非RequestBody的参数绑定也是基于converter转换的),List等
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
//复数依赖 集合类型走这里
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
..required=true matchingBeans为空抛异常..
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
//多个candidate 找到带有@Primary的 多个@Primary会报错 ,如果没有,就根据 找到的bean名称/别名 和形参名称对比,一致就返回
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
// required=true 或者是要单实例 那就只能抛异常了
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
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) {
//如果是class类型 就进行实例化 获得实例 注意:在构造注入时 如果注入了自己 在调用getBean时,会重新触发创建过程,在doGetBean阶段,DefaultSingletonBeanRegistry#beforeSingletonCreation 内部,bean创建之初会将beanName存入singletonsCurrentlyInCreation set中,并判断是否存放成功,如果存放失败,代表之前存在,那就是循环依赖了。 而非构造阶段注入自己,因为已经完成创建过程,bean已存在,直接返回注入自己就好了。不会进入这个if
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
...
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
1.4.1 PropertyPlaceholderHelper#parseStringValue
protected String parseStringValue(
String value, PlaceholderResolver placeholderResolver, @Nullable Set<String> visitedPlaceholders) {
//placeholderPrefix: ${
int startIndex = value.indexOf(this.placeholderPrefix);
if (startIndex == -1) {
return value;
}
StringBuilder result = new StringBuilder(value);
while (startIndex != -1) {
int endIndex = findPlaceholderEndIndex(result, startIndex);
if (endIndex != -1) {
//去除 ${ } ,如${test.num:123} placeholder=test.num:123
String placeholder= = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
String originalPlaceholder = placeholder;
if (visitedPlaceholders == null) {
visitedPlaceholders = new HashSet<>(4);
}
//防止重复解析
if (!visitedPlaceholders.add(originalPlaceholder)) {
throw new IllegalArgumentException(
"Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
}
//递归解析 防止嵌套 正常人也不会这么干
placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
//按key查找 Value 实例中的key就是 test.num:123
String propVal = placeholderResolver.resolvePlaceholder(placeholder);
if (propVal == null && this.valueSeparator != null) {
int separatorIndex = placeholder.indexOf(this.valueSeparator);
if (separatorIndex != -1) {
//找不到就将key 按:拆分 :右边的是默认值,左边的真正的key 示例是:123 真正的key是 test.num
String actualPlaceholder = placeholder.substring(0, separatorIndex);
String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
//拿真正的key再找一遍
propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
if (propVal == null) {
//找不到 返回默认值
propVal = defaultValue;
}
}
}
if (propVal != null) {
// 再来一次 防止默认值是 ${}
propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
...
startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
}
...
}
return result.toString();
}
1.4.1.1 PropertySourcesPropertyResolver#getProperty
protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
if (this.propertySources != null) {
for (PropertySource<?> propertySource : this.propertySources) {
//CompositePropertySource:ConfigPropertySource:DefaultConifg解析apollo的配置 OriginTrackedMapPropertySource解析yml的配置
Object value = propertySource.getProperty(key);
if (value != null) {
if (resolveNestedPlaceholders && value instanceof String) {
//看是不是对应的值也是 ${...} 是的话继续解析
value = resolveNestedPlaceholders((String) value);
}
logKeyFound(key, propertySource, value);
return convertValueIfNecessary(value, targetValueType);
}
}
}
return null;
}
1.5 DefaultListableBeanFactory#resolveMultipleBeans
Class<?> type = descriptor.getDependencyType();
if (descriptor instanceof StreamDependencyDescriptor) {
...
return stream;
}
else if (type.isArray()) {
...
return result;
}
//这里我们只关注 例子中的场景List<Interface>
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
//获取接口类型
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
...排序返回...
return result;
}
else if (Map.class == type) {
...
}
else {
return null;
}
}
1.6 DefaultListableBeanFactory#findAutowireCandidates
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
//这里根据容器持有的beanDefinitionNames 遍历 如果bean已经实例化 根据实例类型进行比较 否则根据beanDefintion targetType比较,其中FactoryBean类型需要实例化调用方法进行比较
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
...
for (String candidate : candidateNames) {
//不是自己注入自己 如果属性上标注了@Qualifier 则必须beanName符合 ,如果属性上没有标明@Qualifier则都符合
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
//如果bean被创建了 返回bean实例 否则返回对应class类型
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty()) {
...
if (result.isEmpty() && !multiple) {
//自己注入自己
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
采用@Bean形式实例化ConstructorResolver#instantiateUsingFactoryMethod 和上述ConstructorResolver#autowireConstructor获取依赖方式一致,
只是筛选调用方法的形式不同,以及调用方法不同,一个是反射调用@Configuration对象的目标方法 ,一个是反射构造器。
另外一点区别就是 autowireConstructor beanDefinition的 autowireMode是 AUTOWIRE_NO ,而 instantiateUsingFactoryMethod的是 AUTOWIRE_CONSTRUCTOR
2.@Autowired
ioc处理机制篇已提过 @Autowired 是populateBean阶段 由AutowiredAnnotationBeanPostProcessor处理,
AbstractAutowireCapableBeanFactory#doCreateBean applyMergedBeanDefinitionPostProcessors方法是 预处理 @Value @Resoure @Inject @Autowired @PostContruct @PreDestroy... ,而applyMergedBeanDefinitionPostProcessors就是调用 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition方法,我们直接看AutowiredAnnotationBeanPostProcessor的
postProcessMergedBeanDefinition,postProcessProperties方法 。
AutowiredAnnotationBeanPostProcessor实现PriorityOrdered ,属于最高优先级BeanPostProcessor
现在new 一个 TestB
public class TestB{
@Resource
private List<IName> names;
@Resource
private IAddress iAddress;
@Resource
public void setName(IName nameB){
log.info("name:{}",nameB);
}
@Autowired
ISex iSex;
@Value("${test.num:123}")
private Integer num;
private Date date;
@Value("${test.date}") // 2020/02/02
public void testDate(Date date){
this.date = date;
}
@Value("#{${test.strs}}") // "1,2"
private List<String> strs;
@PostConstruct
public void init(){
log.info("structure:{}",this);
}
}
2.1 postProcessMergedBeanDefinition
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
扫描@Autowired @Value @Inject属性、方法并保存为Element
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
去重
metadata.checkConfigMembers(beanDefinition);
}
2.1.1 findAutowiringMetadata
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
//基本上就是判断 metadata == null 一般只要处理过就不会处理了
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
...
metadata = buildAutowiringMetadata(clazz);
...
}
return metadata;
}
2.1.2 buildAutowiringMetadata
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//处理属性
ReflectionUtils.doWithLocalFields(targetClass, field -> {
//找到@Autowired @Value @Inject 注解 找到一个就返回
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
...静态属性忽略...
//注解的required字段为true 或者没有required字段(@Inject)
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
//处理方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//和上面处理属性一样 忽略静态方法 不同的是将方法包装成 AutowiredMethodElement
});
elements.addAll(0, currElements);
//一直向上查找父类 直到Object停止
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
//根据elements是否为空 返回空对象
return InjectionMetadata.forElements(elements, clazz);
}
2.2 postProcessProperties
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
//内部就是遍历上面 解析来的 checkedElements/injectedElements 调用 InjectedElement.inject方法 从上面的解析过程看到有两种element,属性和方法
metadata.inject(bean, beanName, pvs);
return pvs;
}
2.2.1 AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
value = resolveFieldValue(field, bean, beanName);
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
2.2.1.1 resolveFieldValue
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
...
try {
// 里面基本调向了 doResolveDependency
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
...如果这次注入的是单实例 将拿到的值缓存起来...
return value;
}
2.2.2 AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
//后面解析也是一样的了 将每个参数包装成MethodParameter 进而调用 doResolveDependency
arguments = resolveMethodArguments(method, bean, beanName);
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
3.@Resource + @PostContruct、@PreDestroy
3.1 postProcessMergedBeanDefinition
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//缓存带@PostConstruct PreDestroy注解 方法
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
//扫描@Resource属性 方法 并保存为 ResourceElement
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
3.1.1 InitDestroyAnnotationBeanPostProcessor#buildLifecycleMetadata
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
return this.emptyLifecycleMetadata;
}
//保存带有@PostContruct注解的方法 所以@PostContruct 这样的方法有多少个调多少个
List<LifecycleElement> initMethods = new ArrayList<>();
//保存带有@PreDestroy注解的方法
List<LifecycleElement> destroyMethods = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<LifecycleElement> currInitMethods = new ArrayList<>();
final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
LifecycleElement element = new LifecycleElement(method);
currInitMethods.add(element);
}
if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
currDestroyMethods.add(new LifecycleElement(method));
}
});
initMethods.addAll(0, currInitMethods);
destroyMethods.addAll(currDestroyMethods);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
new LifecycleMetadata(clazz, initMethods, destroyMethods));
}
3.1.2 CommonAnnotationBeanPostProcessor#buildResourceMetadata
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> {
...
else if (field.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(field.getModifiers())) {
//@Resource不能放在静态属性上 这里比@Autowired更严格 直接抛异常了
throw new IllegalStateException("@Resource annotation is not supported on static fields");
}
...
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//处理方法 和@Autowired不同的是 这里都封装成ResourceElement了 在inject方法中用if区分开了
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
3.2 InjectionMetadata.InjectedElement#inject
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
//getResourceToInject 内部直接调向了 autowireResource
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
}
3.2.1 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();
//不包含这个beanName就和@Autowired 一样 按类型查找
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 {
//包含名称就 直接 调getBean方法了
resource = beanFactory.resolveBeanByName(name, descriptor);
autowiredBeanNames = Collections.singleton(name);
}
}
else {
resource = factory.getBean(name, element.lookupType);
autowiredBeanNames = Collections.singleton(name);
}
...
return resource;
}
综上 @Autowired 和 @Resource 并不仅仅是按类型 按名称查找的简单区别,他们在查找依赖上的功能已经相差无二,不过是作用的处理器不同罢了。
@Resource可以写上随便写个beanName,他就会按类型查找。@Autowired按类型找到多个candidate,他还会再根据beanName再比对一次。
4.AUTOWIRE_BY_NAME,AUTOWIRE_BY_TYPE + AbstractBeanDefinition#propertyValues
现在我们创建一个TestC
public class TestC {
private IAddress iAddress;
private ISex sexA;
private MyImportBeanDefinitionRegistrar.Dummy dummy;
}
一个 ImportBeanDefinitionRegistrar 手动帮我们注册definition
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Data
@AllArgsConstructor
public static class Dummy{
private String name;
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(TestC.class);
builder.addPropertyValue("dummy",new Dummy("from definition"));
builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
registry.registerBeanDefinition(
"testC",
builder.getBeanDefinition());
}
}
然后在任意一个被spring接管的类上 添加 @Import(MyImportBeanDefinitionRegistrar.class) ,然后testC就会被Spring实例化了,这里我们设置的是 AUTOWIRE_BY_NAME
然后我们在testC 的 populateBean阶段打上断点
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
....
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
....
if (pvs != null) {
//调用set方法赋值
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
4.1 AbstractAutowireCapableBeanFactory#autowireByName
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//pvs中不存在 且具备set方法的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
//singletonObjects or beanDefinitionMap存在 beanName
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
//收集起来 在populateBean 方法末尾统一调用
pvs.add(propertyName, bean);
registerDependentBean(propertyName, beanName);
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
//autowireByName 找不到对应的依赖 并不会报错
}
}
}
4.2 AbstractAutowireCapableBeanFactory#autowireByType
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
...
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//同理 又调到了 doResolveDependency
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
//可以看到 autowireByType 比 autowireByName 更严格
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
以上 就是Spring 注入bean及查找依赖的几种方式,还有一种FactoryBean。注意 ,基于FactoryBean创建的bean没有populateBean阶段,只会调用BeanPostProcessor.postProcessAfterInitialization,让其有代理化的可能。